2

将一组通用方法/属性添加到从同一类派生的子类的正确方法是什么?

假设这些是我的基于动物的视频游戏所需的课程(这只是一个例子,我并不是真的在写游戏,但想法是一样的)

class Animal():
    def __init(self, numlegs):
        self.numlegs = numlegs

class Dog(Animal):
    def __init(self, numlegs):
        Animal.__init__(self, numlegs)

    def bark(self):
        print "Arf!"

class Cat(Animal):
    def __init(self, numlegs):
        Animal.__init__(self, numlegs)

    def playwithmouse(self):
        print "It's fun!"

class Duck(Animal):
    def __init(self, numlegs):
        Animal.__init__(self, numlegs)

    def fly(self):
        print "Weee!"

在游戏中的某个时刻 Dog 和 Duck 可以武器化,它们需要具有相同的方法:fire()、reload() 和属性:ammocount。

我认为将它们添加到 Animal() 类中是不正确的,因为在游戏的完全不同的部分中将需要它们。

添加它们的正确方法是什么?

更新 我想补充一点,预期的结果是某种动物 - 武器混合类

class BurtalDuck(Duck):
    fire(): #<- this is somehow added to Duck
        print "ratatatatat!"

我从答案中得到的是,如果我需要整套“武器/弹药”,我可以使用多职业,否则组合就是要走的路。

4

4 回答 4

4

您可以利用 python 中的多重继承,如下所示:

class Weapon():
    def __init__(self):
        self.ammoCount = 0
    def fire():
        print "fire!"
    def reload():
        print "reloading!"

class Dog(Animal, Weapon):
    def __init(self, numlegs):
        Animal.__init__(numlegs)

    def bark(self):
        print "Arf!"

现在你可以这样做:

dog = Dog(4)
dog.fire()

但是,如果Dog只应该,而不是--hybrid ,则使用 的实例并将其作为组件分配给 dog:AnimalAnimalWeaponWeapon

class Dog(Animal, Weapon):
    def __init(self, numlegs):
        Animal.__init__(numlegs)
        self.weapon = Weapon()

    def bark(self):
        print "Arf!"

那你就得用了dog.weapon.fire()。虽然这可能不符合你关于Dog实际武器的概念,但它现在已经被武器化了。:)

如果你有一个狗实例并且你需要它在运行中被武器化,只需利用 python 的动态属性分配

class Dog(Animal):
    def __init(self, numlegs):
        Animal.__init__(numlegs)

    def bark(self):
        print "Arf!"
#some other code maybe
dog = Dog(4)
#more other code
dog.weapon = Weapon()
#even more code
dog.weapon.fire()

一般我会说:

  • 如果您想或成为Dog武器Duck,请使用继承。
  • 如果您想要或Dog包含拥有一个(或多个)武器,请使用组件。Duck
于 2012-06-18T16:07:02.410 回答
3

用作文做到这一点,

class Weapon(object):
    def __init__(self, type):
        self.type = type

class Dog(Animal):
    def __init(self, numlegs):
        Animal.__init__(numlegs)
        self.gun = Weapon("gun")

    def bark(self):
        print "Arf!"
于 2012-06-18T16:15:53.377 回答
2

一种可能性:根本不要将它们添加到类中。创建一个“武器”类,其中包含有关武器如何工作的所有信息,并将该类的一个实例添加到可以是武器的对象中。

当然,这意味着重新考虑你的架构,但这是一个很好的概念。这个想法通常被称为“基于组件”。谷歌搜索“基于组件的游戏对象”并尝试找到一些描述该想法的博客文章/演示文稿。

于 2012-06-18T16:13:38.770 回答
0

另一种方法,使用 mixins:

class Animal(object):
    def __init__(self, n):
        super(Animal,self).__init__()
        if isinstance(n, Animal):  # copy constructor
            self.numlegs = n.numlegs
        else:
            self.numlegs = n
    def do(self):
        pass

class Dog(Animal):
    def do(self):
        print "Arf!"

class Cat(Animal):
    def do(self):
        print "Torturing small animals is fun!"

class Duck(Animal):
    def do(self):
        print "Wheee!"

class Weapon(object):
    def __init__(self):
        super(Weapon,self).__init__()
        self.ammocount = 7

    def fire(self):
        if self.ammocount > 0:
            print "Bang!"
            self.ammocount -= 1
        else:
            print "<click>"

    def reload(self):
        self.ammocount = 7

class WeaponizedDog(Dog, Weapon): pass
class WeaponizedCat(Cat, Weapon): pass
class WeaponizedDuck(Duck, Weapon): pass

max = Dog(4)                # max is a 4-legged dog
max.do()                    # "Arf!"
max = WeaponizedDog(max)    # If I put my hands in my pockets, I'd be carrying concealed deadly weapons...
max.fire()                  # "Bang!"
于 2012-06-18T18:03:57.163 回答