【问题标题】:How does an instance contain multiple instances of other classes?一个实例如何包含其他类的多个实例?
【发布时间】:2016-01-19 21:09:59
【问题描述】:

我正在创建一个基本游戏来帮助理解类,其中 Player() 实例 (Ben) 拥有许多建筑物和单位。每个玩家,例如本,都会拥有各种建筑物,例如飞机工厂或机器人工厂。

class Player:

    def __init__(self):
        self.money = 200
        self.score = 0
        print('Created ')

    def increase_money(self, amount):
        self.money += amount

    def decrease_money(self, amount):
        self.money -= amount

    def check_money(self):
        print(self.money)


class Building(Player):

    def __init__(self):
        self.level = 0
        self.upgrade_cost = 100
        print('created building')

    def upgrade_building(self):
        self.level += 1

    def check_building_level(self):
        print(self.level)

ben = Player()

我意识到,如果我调用Building() 类来创建一个实例,它实际上会创建一个继承玩家属性的建筑实例(即每个建筑都有自己的钱)。

如何让每个玩家包含具有不同属性的各种建筑物和单位?例如,本和比尔有不同的建筑物。在这种情况下,我会使用单个 Player() 类,然后使用 Player() 内部的函数吗?

【问题讨论】:

  • 你不是在寻找继承,而是在寻找组合。您将需要Player 中的一个类变量来管理播放器包含的Buildings 列表。 (而不是从 Player 继承)。
  • 尽管您对该主题感到困惑,但您还是设法写了一个清晰的问题。我希望对于所有提出问题的新用户来说都是如此。 +1

标签: python class oop inheritance


【解决方案1】:

首先,Building 继承自 Player 没有多大意义,BuildingPlayer 之间的 is-a 关系似乎很奇怪,就像一个语义错误。

只是不要从Player继承,即:

class Building(object):
     # code for the class

现在对于您的另一个问题,如果您希望每个 Player 能够聚合 Building 对象的多个实例,您可以使 Player 的每个实例具有一个集合属性(列表或集合)以存储Building 实例。

要做到这一点,你可以添加一行

self.buildings = []

Player__init__ 方法。最初,此列表将为空。要为特定玩家添加建筑物,请附加到其buildings 属性,例如:

p = Player()
p.buildings.append(Building())
p.buildings.append(Building())
p.buildings[1].upgrade_building()

玩家p现在有两座建筑,第二座升级了一次。这只是一个关于如何做到这一点的一般演示。如果没有更多关于您希望您的程序采取的方向的信息,我不能说更多。

【讨论】:

    【解决方案2】:

    你的玩家建筑没有属性来追踪拥有的建筑。您的建筑物也没有所有者。所以你需要:

    class Player:
    
        def __init__(self):
            self.money = 200
            self.score = 0
            self.buildings = []
            print('Created ')
    
        def increase_money(self, amount):
            self.money += amount
    
        def add_building(self, Building):
        #Here's what to call when we construct a new building with the owner
            self.buildings.append(Building):
    
        def decrease_money(self, amount):
            self.money -= amount
    
        def check_money(self):
            print(self.money)
    
    
    class Building:
        def __init__(self, Owner, Type)
    #Constructor now requires an Owner and Type:
            self.level = 0
            self.owner = Owner
            self.Type = Type
            self.upgrade_cost = 100
            print('created building')
            Owner.add_building(self) #And now we will add this to the owner's buildings set
    
        def upgrade_building(self):
            self.level += 1
    
        def check_building_level(self):
            print(self.level)
    

    要创建建筑物,您可以这样称呼它:

    P = player()
    B1 = Building(P, "Building type")
    

    这将添加到玩家拥有的建筑物列表中。此外,您可以查看每个建筑物的所有者(“建造了多少个机器人工厂?”)。您还可以查看玩家的建筑物。

    【讨论】:

    • 忘了提一下,你实例化了同一个类的几个实例,玩家,然后给他们添加不同的建筑: Ben = Player() Bill = Player() B1 = Building(Ben, "type1") B2 = 建筑物(比尔,“type2”)
    【解决方案3】:

    所以这个答案更多是为了参考目的 - 可能正在尝试做同样事情的人。

    我实际上找到了最好的方法,最干净的是从 Player 类中调用 Building 类:

    class Player:
    
        def __init__(self):
            self.money = 200
            self.score = 0
            print('Created ')
            self.bot_factory = Building('Bot Factory') # [1]
            self.vehicle_factory = Building('Vehicle Factory')
    
        def increase_money(self, amount):
            self.money += amount
    
        def decrease_money(self, amount):
            self.money -= amount
    
        def check_money(self):
            print(self.money)
    
    
    class Building(Player):
    
        def __init__(self):
            self.level = 0
            self.upgrade_cost = 100
            print('created building')
    
        def upgrade_building(self):
            self.level += 1
    
        def check_building_level(self):
            print(self.level)
    
    ben = Player()
    

    这样,每个玩家,例如 Ben,都有自己的 bot_factory 和 vehicle_factory 版本。然后,我打算通过诸如ben.building_upgrade('bot','upgrade') 之类的调用来升级建筑物,该调用从 Player 类中调用 Building 函数。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多