子類別也可依需要改寫 (override) 父類別的方法,這是說子類別需要用到與父類別具有相同名稱的方法,但是子類別需要的功能有所修改、擴充或增加,因此當子類別裡頭定義與父類別相同名稱的方法時,就會改寫父類別的方法。經過改寫,子類別的方法完全屬於子類別所有,例如以下程式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | class Demo: __x = 0 def __init__( self , i): self .__i = i Demo.__x + = 1 def __str__( self ): return str ( self .__i) def hello( self ): print ( "hello " + self .__str__()) @classmethod def getX( cls ): return cls .__x class SubDemo(Demo): def __init__( self , i, j): self .__i = i self .__j = j def __str__( self ): return str ( self .__i) + "+" + str ( self .__j) a = SubDemo( 1234 ) a.hello() print ( "a.__x =" , a.getX()) b = SubDemo( 56 , 78 ) b.hello() print ( "b.__x =" , b.getX()) print () print ( "a.__x =" , a.getX()) print ( "b.__x =" , b.getX()) # 《程式語言教學誌》的範例程式 # 檔名:cla19.py # 功能:示範 Python 程式 # 作者:張凱慶 # 時間:西元 2010 年 12 月 |
執行結果如下

Demo 為父類別,定義四個方法, SubDemo 為子類別,改寫 Demo 的兩個方法,包括 __init__() 與 __str__() 。
我們可以發現, Demo 有個 __x 變數,原本用來算有多少 Demo 實體 (instance) 被建立,我們想這應該要包括子類別 SubDemo 的實體數量,也就是說, __x 應該等於 Demo 實體總數加上 SubDemo 實體總數。此例中我們建立兩個 SubDemo 實體,可是 __x 卻等於 0 。
這是為什麼呢?因為此例中 Demo 的 __init__() 方法從頭到尾沒有被呼叫過,因此 __x 始終保持為初值 0 。解決這個問題的方法很簡單,一個幾單的途徑是在子類別 SubDemo 新增一個 __x ,但是這樣一來就只能累計 SubDemo 的實體數量,若是還有其他子類別繼承自 Demo ,這就無法一同列入計算了。
另一個解決途徑是在子類別改寫的方法中先呼叫 (call) 父類別的方法,這可利用內建函數 (function) super() ,如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | class Demo: __x = 0 def __init__( self , i): self .__i = i Demo.__x + = 1 def __str__( self ): return str ( self .__i) def hello( self ): print ( "hello " + self .__str__()) @classmethod def getX( cls ): return cls .__x class SubDemo(Demo): def __init__( self , i, j): super ().__init__(i) self .__j = j def __str__( self ): return super ().__str__() + "+" + str ( self .__j) a = SubDemo( 12 , 34 ) a.hello() print ( "a.__x =" , a.getX()) b = SubDemo( 56 , 78 ) b.hello() print ( "b.__x =" , b.getX()) print () print ( "a.__x =" , a.getX()) print ( "b.__x =" , b.getX()) # 《程式語言教學誌》的範例程式 # 檔名:cla20.py # 功能:示範 Python 程式 # 作者:張凱慶 # 時間:西元 2010 年 12 月 |
執行結果如下

第 19 行到第 21 行
19 20 21 | def __init__( self , i, j): super ().__init__(i) self .__j = j |
SubDemo 的 __init__() 定義中,我們利用 super() 呼叫父類別 Demo 的 __init__() ,因此需提供 i 當作參數 (parameter) 。注意,這裡 self.__i 變成父類別的私有屬性。
第 23 行到第 24 行
23 24 | def __str__( self ): return super ().__str__() + "+" + str ( self .__j) |
這裡的 __str__() ,在 return 後的運算式 (expression) 先呼叫 super().__str__() ,因為 self.__i 已經變成父類別 Demo 私有屬性,因此需要先呼叫父類別的 __str__() 。
中英文術語對照 | |
---|---|
子類別 | subclass |
屬性 | attribute |
方法 | method |
父類別 | superclass |
繼承 | inherit |
改寫 | override |
實體 | instance |
呼叫 | call |
函數 | function |
參數 | parameter |
運算式 | expression |
參考資料
http://docs.python.org/py3k/tutorial/classes.html
http://docs.python.org/py3k/reference/compound_stmts.html
http://docs.python.org/py3k/tutorial/classes.html
http://docs.python.org/py3k/reference/compound_stmts.html
1 則留言:
在第一個範例裡
a = SubDemo(1234)應該會報錯
因為找不到只吃一個引數的SubDemo建構子
張貼留言