多重继承的问题
我刚开始学习编程,Python是我学的第一门语言。我在研究多重继承的时候,写了下面这个程序:
class animal:
def __init__(self, name, species):
self.name = name
self.species = species
def show(self):
print(f"Name : {self.name}")
print(f"Species : {self.species}")
class dog(animal):
def __init__(self, name, breed):
animal.__init__(self, name, species="Dog")
self.breed = breed
def show(self):
animal.show(self)
print(f"Breed : {self.breed}")
class cat(animal):
def __init__(self, name, breed):
animal.__init__(self, name, species="Cat")
self.breed = breed
def show(self):
animal.show(self)
print(f"Breed : {self.breed}")
class anicolor(dog, cat):
def __init__(self, name, breed, color):
dog.__init__(self, name, breed)
cat.__init__(self, name, breed)
self.color = color
def show(self):
print(dog.show(self), cat.show(self))
print(f"Color : {self.color}")
d = anicolor("Tommy", "German Shepherd", "Black")
c = anicolor("Kitty", "Persian", "White")
d.show()
c.show()
我期待的输出是:
Name : Tommy
Species : Dog
Breed : German Shepherd
Color : Black
Name : Kitty
Species : Cat
Breed : Persian
Color : White
输出中主要的问题是,tommy的物种显示为猫,而不是狗,因为猫的类构造函数写在狗的类构造函数后面。那么我该怎么解决这个问题呢?
Name : Tommy
Species : Cat
Breed : German Shepherd
Name : Tommy
Species : Cat
Breed : German Shepherd
None None
Color : Black
Name : Kitty
Species : Cat
Breed : Persian
Name : Kitty
Species : Cat
Breed : Persian
None None
Color : White
1 个回答
2
这里有一个替代的类结构,它可以正常工作,并且仍然利用了多重继承的特点:
class Animal:
def __init__(self, name, species):
self.name = name
self.species = species
def show(self):
print(f"Name : {self.name}")
print(f"Species : {self.species}")
class Colored:
def __init__(self, color, **kwargs):
super().__init__(**kwargs)
self.color = color
def show(self):
super().show()
print(f"Color : {self.color}")
class WithBreed:
def __init__(self, breed, **kwargs):
super().__init__(**kwargs)
self.breed = breed
def show(self):
super().show()
print(f"Breed : {self.breed}")
class Dog(WithBreed, Colored, Animal):
def __init__(self, **kwargs):
super().__init__(species="Dog", **kwargs)
class Cat(WithBreed, Colored, Animal):
def __init__(self, **kwargs):
super().__init__(species="Dog", **kwargs)
d = Dog(name="Tommy", breed="German Shepherd", color="Black")
c = Cat(name="Kitty", breed="Persian", color="White")
d.show()
c.show()
在这个例子中,Animal
是我们的基础类,而 Colored
和 WithBreed
是可以应用于任何类的“混合类”。
我们把 Cat
(猫)和 Dog
(狗)定义为具有 Colored
和 WithBreed
特性的 Animal
类型。
每个类只关注它所关心的参数,其他的参数则通过 kwargs
传递,这样你就可以在不更新每个类代码的情况下,改变基础类的定义,或者添加和移除混合类。
(如果我们进一步思考这个类结构,可能会发现 WithBreed
只对动物有意义,所以它可能不应该是一个单独的类,而应该作为 Animal
的一部分,但 Colored
混合类可能会用于其他类型的东西,比如 Vehicle
(车辆)或 Milkshake
(奶昔),所以作为混合类是合理的。)