Python 如何将相同的方法/属性添加到从公共类派生的一组子类中
向派生自同一类的子类添加一组通用方法/属性的正确方法是什么 假设这些是我的课程,我需要一个基于动物的视频游戏(这只是一个例子,我不是在写游戏,但想法是一样的) 在游戏中的某一时刻,狗和鸭可以被武器化,它们需要有相同的方法:fire()、reload()和properties:ammocount 我认为将它们添加到Animal()类中是不正确的,因为在游戏的另一个完全不同的部分中需要它们 添加它们的正确方法是什么 更新 我想补充一点,预期的结果是 动物武器混合类Python 如何将相同的方法/属性添加到从公共类派生的一组子类中,python,class,subclass,Python,Class,Subclass,向派生自同一类的子类添加一组通用方法/属性的正确方法是什么 假设这些是我的课程,我需要一个基于动物的视频游戏(这只是一个例子,我不是在写游戏,但想法是一样的) 在游戏中的某一时刻,狗和鸭可以被武器化,它们需要有相同的方法:fire()、reload()和properties:ammocount 我认为将它们添加到Animal()类中是不正确的,因为在游戏的另一个完全不同的部分中需要它们 添加它们的正确方法是什么 更新 我想补充一点,预期的结果是 动物武器混合类 class BurtalDuck(
class BurtalDuck(Duck):
fire(): #<- this is somehow added to Duck
print "ratatatatat!"
class-BurtalDuck(Duck):
fire():#您可以利用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()
如果狗
只被认为是动物
,而不是动物
-武器
-杂种,则使用武器
的实例并将其作为组件分配给狗:
class Dog(Animal, Weapon):
def __init(self, numlegs):
Animal.__init__(numlegs)
self.weapon = Weapon()
def bark(self):
print "Arf!"
然后你必须使用狗.武器.火()。这可能不符合你的概念,狗实际上是一种武器,但它现在已经武器化了
如果您有一个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()
一般来说,我会说:
- 如果你想
狗
或鸭
成为武器,请使用继承
- 如果您希望
狗
或鸭
由一件(或多件)武器组成或拥有一件(或多件),请使用组件
一种可能性:根本不要将它们添加到类中。创建一个“武器”类,该类包含有关武器如何工作的所有信息,并将该类的实例添加到可以成为武器的对象中
当然,这意味着要重新思考一下您的体系结构,但这是一个值得思考的概念。这种想法通常被称为“基于组件”。并试着找到一些描述这个想法的博客帖子/演示文稿。通过写作来实现这一点
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!"
另一种方法是使用mixin:
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!"
类动物(对象):
定义初始化(self,n):
超级(动物,自我)。\uuuuu初始
如果是实例(n,动物):#复制构造函数
self.numlegs=n.numlegs
其他:
self.numlegs=n
def do(自我):
通过
犬类(动物):
def do(自我):
打印“Arf!”
类别猫(动物):
def do(自我):
印刷“折磨小动物很有趣!”
鸭类(动物):
def do(自我):
打印“Wheee!”
类武器(对象):
定义初始化(自):
超级(武器,自我)。\uuuuuuu初始
self.ammocount=7
def火灾(自):
如果self.ammocount>0:
打印“砰!”
self.ammocount-=1
其他:
打印“”
def重新加载(自):
self.ammocount=7
职业武器装备日志(狗,武器):通过
职业武器猫(猫,武器):通过
职业武器化鸭子(鸭子,武器):传球
马克斯=狗(4)#马克斯是一只四条腿的狗
max.do()#“Arf!”
马克斯=武器化(马克斯)#如果我把手放在口袋里,我会随身携带隐藏的致命武器。。。
max.fire()#“砰!”
不,这不是家庭作业,谢谢你问=)+1关于武器化鸭子的想法。我不知道混合体是什么,现在就查它们。@DSM(+1,如果你有参考资料的话),这就是为什么我去任何地方都会有我的猎鸭炭疽。好吧,再次编辑评论,我只想保留狗的a类动物亚类,并且只在我代码的另一部分将它们武器化(想象一下,在游戏的第2版中,我希望使用相同的类而不修改它们),我建议使用接口,但据我所知,python不支持:)也感谢您扩展了答案,阅读马克·希尔德雷思(MarkHildreth)关于继承与构成的问题的链接,一切都变得更加清晰。我很高兴我能提供帮助。:)使用组合而不是继承对于解耦尤其重要,并且经常用于实现。我肯定会仔细看一看。所谓“添加实例”,是指将其分配给类中的某个变量?这似乎不是很oop(但我是谁来说什么是oop?=)这可以归结为继承(您试图完成的)和组合(我的建议)之间的决定。他们有自己的优点和缺点,也有使用他们的人的偏见。以下问题提供了更多信息,可用于确定什么是好方法:
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!"