考虑以下Python代码:
class Parent(object):
def __init__(self, name, serial_number):
self.name = name
self.serial_number = serial_number
class ChildA(Parent):
def __init__(self, name, serial_number):
self.name = name
self.serial_number = serial_number
super(ChildA, self).__init__(name = self.name, serial_number = self.serial_number)
def speak(self):
print("I am from Child A")
class ChildB(Parent):
def __init__(self, name, serial_number):
self.name = name
self.serial_number = serial_number
super(ChildB, self).__init__(name = self.name, serial_number = self.serial_number)
def speak(self):
print("I am from Child B")
class GrandChild(ChildA, ChildB):
def __init__(self, a_name, b_name, a_serial_number, b_serial_number):
self.a_name = a_name
self.b_name = b_name
self.a_serial_number = a_serial_number
self.b_serial_number = b_serial_number
super(GrandChild, self).__init_( something )
在GrandChild中运行super
函数时,如何正确格式化__init__
参数,以使ChildA和ChildB都获得正确的参数?
另外,如何从GrandChild类中访问speak
方法的两个不同版本(ChildA的版本和ChildB的版本)?
3条答案
按热度按时间xkftehaa1#
所以,当你从孙调用super时,
ChildA
的__init__
方法将被调用,因为super遵循__mro__
属性(父代从左到右,然后祖父母从左到右,然后曾祖父母,...)由于
ChildA
的init也调用super,那么所有的super调用将被链接,调用子b的__init__
,并最终调用父init。要做到这一点,您的界面通常需要保持一致。也就是说,位置参数需要意味着相同的事情,并且按照顺序。
在情况并非如此的情况下,关键字参数可能会更好地工作。
还要注意,在您的代码中,name和serial在所有类之间被重用为示例属性,这可能不是您想要的。
sqxo8psd2#
在python中,你可以显式地调用你的父类上的一个特定方法:
请注意,当以这种方式调用时,需要显式地将
self
放入。您也可以像以前一样使用
super()
方式,它将调用“第一个”父节点。确切的顺序是动态的,但默认情况下,它将对继承层次结构进行从左到右、深度优先的预排序扫描。因此,您的super()
调用将仅在ChildA
上调用__init__
。bzzcjhmw3#
钻石问题在Python中不存在,因为它优先考虑首先继承的类。
输出为A内部
在上面的示例中,**GrandChild(ChildA,ChildB)**表示类GrandChild首先继承类ChildA,然后继承类ChildB。
一旦你在D中声明了printName()方法,那么输出将是在孙子中。如果你在GC类中交换了继承的子元素的位置,那么:
输出为B内