子类调用父类同名方法总结
问题:
class Master(object): def __init__(self): self.kongfu = "古法煎饼果子配方" # 实例变量,属性 def make_cake(self): # 实例方法,方法 print("[古法] 按照 <%s> 制作了一份煎饼果子..." % self.kongfu) # 父类是 Master类 class School(Master): def __init__(self): self.kongfu = "现代煎饼果子配方" def make_cake(self): print("[现代] 按照 <%s> 制作了一份煎饼果子..." % self.kongfu) super().__init__() # 执行父类的构造方法 super().make_cake() # 执行父类的实例方法 # 父类是 School 和 Master class Prentice(School, Master): # 多继承,继承了多个父类 def __init__(self): self.kongfu = "猫氏煎饼果子配方" def make_cake(self): self.__init__() # 执行本类的__init__方法,做属性初始化 self.kongfu = "猫氏...." print("[猫氏] 按照 <%s> 制作了一份煎饼果子..." % self.kongfu) def make_all_cake(self): # 方式1. 指定执行父类的方法(代码臃肿) # School.__init__(self) # School.make_cake(self) # # Master.__init__(self) # Master.make_cake(self) # # self.__init__() # self.make_cake() # 方法2. super() 带参数版本,只支持新式类 # super(Prentice, self).__init__() # 执行父类的 __init__方法 # super(Prentice, self).make_cake() # self.make_cake() # 方法3. super()的简化版,只支持新式类 super().__init__() # 执行父类的 __init__方法 super().make_cake() # 执行父类的 实例方法 self.make_cake() # 执行本类的实例方法 damao = Prentice() damao.make_cake() damao.make_all_cake() # print(Prentice.__mro__)
知识点:
子类继承了多个父类,如果父类类名修改了,那么子类也要涉及多次修改。而且需要重复写多次调用,显得代码臃肿。
使用super() 可以逐一调用所有的父类方法,并且只执行一次。调用顺序遵循 mro 类属性的顺序。
注意:如果继承了多个父类,且父类都有同名方法,则默认只执行第一个父类的(同名方法只执行一次,目前super()不支持执行多个父类的同名方法)
super() 在Python2.3之后才有的机制,用于通常单继承的多层继承。
# 古法师傅类 class Master(object): def make_cake(self): print("制作古法煎饼果子") # 现代师傅类 class School(object): def make_cake(self): print("制作现代煎饼果子") # 徒弟类 class Prentice(Master, School): # 猫式 def make_cake(self): print("制作猫式煎饼果子") # 古法 def make_old_cake(self): # 子类继承了父类 子类重写了父类的同名方法 # 导致子类无法继承父类的同名方法 # 需求: 在子类中使用父类的同名方法 # 在不考虑到修改父类名的情况下 使用01方式更加方便 # Master.make_cake(self) # 以下两种方式是遵循 继承链 # 02和03 适用于单继承 或者在多继承中只想调用第一个父类的方法 # 格式02:super(子类名, self).同名方法的名() super(Prentice, self).make_cake() # 格式03: 02的简写 # super().make_cake() # 现代 def make_new_cake(self): # School.make_cake(self) super().make_cake() # 对象 dm = Prentice() print(Prentice.__mro__) dm.make_cake() dm.make_old_cake() dm.make_new_cake()