Python 速查手冊

6.7 繼承

本書已有新版,請參考 Python 簡易手冊 - 目錄

繼承 (inheritance) 是物件導向程式設計 (object-oriented programming) 的主要特性之一,讓類別 (class) 設計可以有共通屬性 (attribute) 及共通方法 (method) ,這些共通的部分是在父類別 (superclass) 定義,子類別 (subclass) 繼承父類別之後就取得父類別的屬性及方法,子類別還可以定義自己專用的屬性及方法。

繼承的英文動詞原文為 inherit ,意思泛指從什麼得到什麼,中文意思除了繼承外,遺傳上也是用這個詞,就物件導向程式設計而言,意思比較接近遺傳,也就是子類別從父類別得到屬性及方法,子類別與父類別仍會同時存在,

然而繼承中文的原本意思是指先人去世,後人繼承先人的財產、精神等等,程式設計中卻沒有這種意味,因此需要特別留意,此外由於繼承是很久以前的翻譯用詞,也已經變成物件導向程式設計中的慣用詞,因此我們仍然是沿用繼承一詞。

繼承的寫法很簡單,這裡 Demo 當作父類別, Demo2 為子類別,就在 Demo2 的識別字 (identifier) 後面加上小括弧,小括弧中寫上要繼承的父類別名稱,這樣 Demo2 就繼承了 Demo

class Demo:
    pass
    
class Demo2(Demo):
    pass

#《程式語言教學誌》的範例程式
# http://kaiching.org/
# 檔名:inherit01.py
# 功能:示範定義類別
# 作者:張凱慶

內建函數 (built-in function) isinstance() 可用來判斷變數 (variable) 是否為某類別的實體 (instance) 物件 (object) ,第一個參數為變數名稱,第二個參數為類別名稱,這裡由於變數 d 就是 Demo 的實體物件,因此回傳 True 。另一個內建函數 issubclass() 則是判斷第一個參數是否為第二個參數的子類別,由於此例 Demo2Demo 的子類別,因此回傳 True

from inherit01 import Demo
from inherit01 import Demo2

d = Demo()
print(isinstance(d, Demo))
print(issubclass(Demo2, Demo))

#《程式語言教學誌》的範例程式
# http://kaiching.org/
# 檔名:inherit02.py
# 功能:示範定義類別
# 作者:張凱慶

於命令列執行以上程式,結果如下

$ python3 inherit02.py
True
True
$

這裡看到 Demo4 繼承 Demo3 ,類別屬性 (class attribute) i 及實體屬性 (instance attribute) j 都會被繼承

class Demo3:
    i = 0
    
    def __init__(self):
        self.j = 0
        Demo3.i += 1

class Demo4(Demo3):
    pass

d1 = Demo3()
print(d1.i, d1.j)
d2 = Demo4()
print(d2.i, d2.j)

#《程式語言教學誌》的範例程式
# http://kaiching.org/
# 檔名:inherit03.py
# 功能:示範定義類別
# 作者:張凱慶

於命令列執行以上程式,結果如下

$ python3 inherit03.py
1 0
2 0
$

這裡 Demo5 同樣繼承 Demo3 ,由於 Demo5 改寫 (override) 了 __init__() 方法,因此實體屬性 j 並沒有被繼承

from inherit03 import Demo3

class Demo5(Demo3):
    def __init__(self):
        self.k = 0

d3 = Demo5()
print(d3.i, d3.j, d3.k)

#《程式語言教學誌》的範例程式
# http://kaiching.org/
# 檔名:inherit04.py
# 功能:示範定義類別
# 作者:張凱慶

於命令列執行以上程式,結果如下

$ python3 inherit04.py
1 0
2 0
Traceback (most recent call last):
  File "inherit04.py", line 8, in <module>
    print(d3.i, d3.j, d3.k)
AttributeError: 'Demo5' object has no attribute 'j'
$

如果改寫過的 __init__() 方法要繼承原有的實體屬性,就要用內建函數 super() 先呼叫父類別的 __init__() 方法,例如這裡 Demo6__init__() 方法就先用 super() 呼叫,因此實體屬性 j 就被繼承到 Demo6 中了

from inherit03 import Demo3

class Demo6(Demo3):
    def __init__(self):
        super().__init__()
        self.k = 0

d4 = Demo6()
print(d4.i, d4.j, d4.k)

#《程式語言教學誌》的範例程式
# http://kaiching.org/
# 檔名:inherit05.py
# 功能:示範定義類別
# 作者:張凱慶

於命令列執行以上程式,結果如下

$ python3 inherit05.py
1 0
2 0
3 0 0
$

相關教學影片

上一頁: 6.6 封裝
Python 速查手冊 - 目錄
下一頁: 6.8 子類別的方法改寫
回 Python 教材首頁
回程式語言教材首頁