笨方法學python3筆記: ex44繼承與合成

我們的OOP程序員,就像英雄永遠會遇險一樣,總會遇到叫繼承的“天險”。

老道的程序員會盡力避開這道天險,因爲他們知道這裏水有多深。

直接說結論吧:所有繼承都能用合成來替代,而多重繼承無論如何都要避免。

主要概念及其英文

  1. 類:class
  2. 繼承:inheritance
  3. 合成:composition

繼承

繼承意思是一個子類會“繼承”母類的大多數特徵。子母類的交互方式有:子imply/override/alter母的action。

  1. 隱式繼承(implicit): 當你調用子類的一個函數,python會先在子類中找,如果子類沒有,會再去母類中找。若在母類中找到,則屬於implicit
  2. 顯示覆蓋(override):在子類定義母類中有的一個函數,python在子類找到後,就直接用了。也就是覆蓋了母類的這個函數
  3. 改動(alter):使用super函數

ex44_inherit.py

class Parent(object):
    
    def implicit(self):
        print("PARENT implicit()")
    def override(self):
        print("PARENT override()")
    def altered(self):
        print("PARENT altered()")
        
class Child(Parent):
    
    def override(self):
        print("CHILD override()")
    def altered(self):
        print("CHILD, BEFORE PARENT altered()")
        super(Child, self).altered()
        print("CHILD, AFTER PARENT altered()")

dad = Parent()
son = Child()

dad.implicit()
son.implicit()

dad.override()
son.override()

dad.altered()
son.altered()

爲啥用 super()

書裏大概是說可以用來處理多重繼承:

class SuperFun(Child, BadStuff):
    pass

且多重繼承多半用於如下情況。

using super() with __init__
class Child(Parent):
    
    def __init__(self, stuff):
        self.stuff = stuff
        super(Child, self).__init__()# 

然而沒說在多重繼承中怎麼用。

合成

合成也能完成繼承的任務,比如:

ex44e.py

class Other(object):
    
    def override(self):
        print("OTHER override()")
        
    def implicit(self):
        print("OTHER implicit()")
        
    def altered(self):
        print("OTHER altered()")
        
class Child(object):
    
    def __init__(self):
        self.other = Other()
        
    def implicit(self):
        self.other.implicit()
        
    def override(self):
        print("CHILD override()")
        
    def altered(self):
        print("CHILD, BEFORE OTHER altered()")
        self.other.altered()
        print("CHILD, AFTER OTHER altered()")
        
son = Child()

son.implicit()
son.override()
son.altered()

這個Other類可以另存爲.py文件,然後當做模塊導入。或許就叫other.py

繼承還是合成?

  1. 極力避免多重繼承——它要花很多精力去學習,卻只能帶來一點方便

  2. 如果要在許多不同且無關的情況下用到重複的代碼,請使用合成處理代碼。

  3. 只有在代碼之間可以用一個變量連接或非用不可時,纔去用繼承

不要成爲規則的奴隸,該用還是要用的。比如你的合作者或同事已經用了多重繼承去寫代碼。

課後作業

閱讀python的代碼規範,盡力按其中的要求寫代碼。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章