为从同一个类派生的子类添加一组通用方法/属性的正确方法是什么?
让我们说这些是基于动物的视频游戏所需要的课程(这只是一个例子,我不是在写游戏,但想法是一样的)
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 and Duck可以被武器化,并且它们需要具有相同的方法:fire(),reload()和属性:ammocount。
我不认为在Animal()类中添加它们是正确的,因为它们将在游戏的完全不同的部分中被需要。
添加它们的正确方法是什么?
更新 我想补充一点,预期的结果是某种 动物 - 武器混合类如
class BurtalDuck(Duck):
fire(): #<- this is somehow added to Duck
print "ratatatatat!"
我从答案中得到的结果是,如果我需要整套“武器/ ammos”,我可以使用多重分类,否则构图就可以了。
答案 0 :(得分: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
只 <{1}},而不是Animal
- {{1} } -hybrid,然后使用Animal
的实例并将其作为组件分配给狗:
Weapon
然后你必须使用Weapon
。这可能不符合class Dog(Animal, Weapon):
def __init(self, numlegs):
Animal.__init__(numlegs)
self.weapon = Weapon()
def bark(self):
print "Arf!"
实际上 武器的概念,但它现在被武器化了。 :)
如果您有一个狗实例,并且您需要它即时进行武器化,只需利用python的动态属性分配
dog.weapon.fire()
一般来说,我会说:
Dog
或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
包含或拥有一个(或多个)武器,请使用组件。答案 1 :(得分: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!"
答案 2 :(得分:2)
一种可能性:根本不要将它们添加到类中。创建一个“武器”类,其中包含有关武器如何工作的所有信息,并将该类的实例添加到可以作为武器的对象中。
当然,这意味着对您的架构进行一点反思,但这是一个值得思考的好概念。这个想法通常以“基于组件”为名。 Google for "component-based game objects"并试着找一些描述这个想法的博客文章/演示文稿。
答案 3 :(得分: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!"