关于多重继承在子类的__init__方法中到底应该调用哪个父类的__init__
我想问下 假设 C继承了A和B 其中A的init有两个参数,B的init有三个参数,这几个参数都没有啥特别的关系,然后我在写C的init函数的时候,里面的super应该咋写,到底以哪个父类的为准。这块儿我比较疑惑。
我想问下 假设 C继承了A和B 其中A的init有两个参数,B的init有三个参数,这几个参数都没有啥特别的关系,然后我在写C的init函数的时候,里面的super应该咋写,到底以哪个父类的为准。这块儿我比较疑惑。
2023-10-08
# 关于你这个情况,我尝试了两种理解方法,我自己称为显示调用和继承式调用,具体代码如下:
class Person(object):
def __init__(self, name, gender):
self.name = name
self.gender = gender
class Student(Person):
def __init__(self, name, gender, score):
super(Student, self).__init__(name, gender)
self.score = score
class Teacher(Person):
def __init__(self, name, gender, course):
super(Teacher, self).__init__(name, gender)
self.course = course
class Skill(object):
def __init__(self, sport):
self.sport = sport
class PlayBasketball(Skill):
def __init__(self, sport):
super(PlayBasketball, self).__init__(sport)
class PlayFootball(Skill):
def __init__(self, sport):
super(PlayFootball, self).__init__(sport)
# 显示地调用父类的init初始化方法
class StudentBasketball(PlayBasketball, Student):
def __init__(self, name, gender, score, sport):
Student.__init__(self, name, gender, score)
PlayBasketball.__init__(self, sport)
def can_play(self):
return 'I am %s ,i am %s, i got score %s ,i can play%s' % (self.name, self.gender, self.score, self.sport)
# 显示地调用父类的init初始化方法
class TeacherFootball(PlayFootball, Teacher):
def __init__(self, name, gender, course, sport):
Teacher.__init__(self, name, gender, course)
PlayFootball.__init__(self, sport)
def can_play(self):
return 'I am %s ,i am %s,i teach %s ,i can play%s' % (self.name, self.gender, self.course, self.sport)
# 继承式地调用父类的init初始化方法
class StudentPlayBasketball(PlayBasketball, Student):
def __init__(self, name, gender, score, sport):
super(StudentPlayBasketball, self).__init__(name, gender, score)
super(StudentPlayBasketball, self).__init__(sport)
def can_play(self):
return 'I am %s ,i am %s, i got score %s ,i can play%s' % (self.name, self.gender, self.score, self.sport)
# 继承式地调用父类的init初始化方法
class TeacherPlayFootball(PlayFootball, Teacher):
def __init__(self, name, gender, course, sport):
super(TeacherPlayFootball, self).__init__(name, gender, course)
super(TeacherPlayFootball, self).__init__(sport)
def can_play(self):
return 'I am %s ,i am %s,i teach %s ,i can play%s' % (self.name, self.gender, self.course, self.sport)
student = StudentBasketball('Jason', 'Male', 98, 'Basketball')
teacher = TeacherFootball('Alice', 'Female', 'English', 'Football')
student1 = StudentBasketball('Jason', 'Male', 98, 'Basketball')
teacher2 = TeacherFootball('Alice', 'Female', 'English', 'Football')
print(student1.can_play())
print(teacher2.can_play())
在Python中,当类C继承自类A和类B,并且A和B的__init__
方法需要不同数量的参数时,你需要在类C的__init__
方法中显式地调用这两个父类的__init__
方法。由于Python的super()
函数用于调用父类的方法,但它不会自动处理不同数量的参数问题,因此你需要手动调用每个父类的__init__
方法,并传递必要的参数。
以下是一个例子,展示了如何在类C的__init__
方法中调用类A和类B的__init__
方法:
class A: def __init__(self, name, age): self.name = name self.age = age class B: def __init__(self, name, sex, height): self.name = name self.sex = sex self.height = height class C(A, B): def __init__(self, name, age, sex, height): # 显式调用A的__init__方法 A.__init__(self, name, age) # 显式调用B的__init__方法 B.__init__(self, name, sex, height) # 创建C的实例 c = C("Alice", 30, "female", 165) print(c.name) # 输出: Alice print(c.age) # 输出: 30 print(c.sex) # 输出: female print(c.height) # 输出: 165
在上面的例子中,类C的__init__
方法接受所有必要的参数,然后分别调用类A和类B的__init__
方法。注意,这里我们直接调用了A和B的__init__
方法,而不是使用super()
。这是因为super()
用于调用当前类在MRO(方法解析顺序)中的下一个父类的方法,但它不会处理不同数量的参数问题。由于类A和类B的__init__
方法需要不同的参数集,直接调用它们是最直接和清晰的方式。
如果你坚持想要使用super()
,那么你必须确保你的继承结构以及__init__
方法的参数设计允许这样做。这通常意味着你需要设计一个统一的参数列表,这个列表可以包含所有父类__init__
方法所需的参数。然而,在你的情况下,由于参数之间没有直接的关系,并且它们各自属于不同的父类,这可能会变得非常复杂且不直观。因此,直接调用每个父类的__init__
方法通常是更合适的选择。
举报