子類調用父類同名方法總結
問題:
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()