Python 簡易手冊

單元 62 - 繼承

Python 是物件導向程式語言 (object-oriented programming language) ,物件導向程式設計 (object-oriented programming) 有三大特性,分別是封裝 (encapsulation) 、繼承 (inheritance) 與多型 (polymorphism) 。所謂繼承其實只是讓類別能從其他類別擴充,也就是把共通功能放在父類別 (superclass) ,由子類別 (subclass) 繼承父類別,讓子類別具有共通功能,同時子類別可以額外定義專屬功能。

中文繼承隱含長輩死去,晚輩繼承遺產的意思,但是在物件導向程式中並沒有這個意思,事實上程式執行時,父類別跟子類別是同時存在的,但是早期把 inherit 翻譯成「繼承」,這裡是繼續沿用「繼承」及相關的翻譯方式。

以下示範繼承的寫法

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
# 定義父類別
class Demo:
    pass

# 定義子類別
class Demo2(Demo):
    pass

# 印出類別
print(Demo)
print(Demo2)

# 檔名: class_demo22.py
# 說明: 《Python簡易手冊》的範例
# 網址: http://kaiching.org
# 作者: Kaiching Chang
# 時間: 2024 年 3 月

單元 54 - 類別介紹類別 (class) 的基本概念,單元 61 - 封裝介紹物件導向程式設計的第一項特性 - 封裝,單元 64 - 多型會介紹物件導向程式設計的第三項特性 - 多型,單元 49 - pass 陳述與省略符號 ...介紹關鍵字 (keyword) pass 的用法。

繼承是在子類別識別字 (identifier) 後面加上小括弧,小括弧中是父類別的識別字

 5
 6
 7
# 定義子類別
class Demo2(Demo):
    pass

底下是印出類別名稱,執行結果如下

> python class_demo22.py
<class '__main__.Demo'>
<class '__main__.Demo2'>
>

內建函數 (built-in function) isinstance() 可以判斷參數 (parameter) 是否為某類別的實體物件,另一個內建函數 issubclass() 則可以判斷第一個參數是否為第二個參數的子類別,例如

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
# 定義父類別
class Demo:
    pass

# 定義子類別
class Demo2(Demo):
    pass

# 建立物件
a = Demo()
b = Demo2()
# 判斷 a 是否為 Demo 的實體
print(isinstance(a, Demo))
# 判斷 Demo2 是否是 Demo 的子類別
print(issubclass(Demo2, Demo))

# 檔名: class_demo23.py
# 說明: 《Python簡易手冊》的範例
# 網址: http://kaiching.org
# 作者: Kaiching Chang
# 時間: 2024 年 3 月

此例判斷變數 a 是否為 Demo 類別的實體,另外判斷 Demo2 類別是否為 Demo 類別的子類別,執行結果如下

> python class_demo23.py
True
True
>

子類別物件預設可以直接使用父類別的屬性 (attribute) 跟方法 (method) ,但是如果子類別定義跟副類別相同名稱的方法,就會以子類別定義的為主,這叫做改寫 (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
# 定義父類別
class Demo:
    # 父類別的方法
    def do_something(self):
        print("aaa")

# 定義子類別
class Demo2(Demo):
    pass

# 定義子類別
class Demo3(Demo):
    # 改寫父類別的方法
    def do_something(self):
        print("bbb")

# 建立物件
a = Demo()
b = Demo2()
c = Demo3()
# 呼叫方法
a.do_something()
b.do_something()
c.do_something()

# 檔名: class_demo24.py
# 說明: 《Python簡易手冊》的範例
# 網址: http://kaiching.org
# 作者: Kaiching Chang
# 時間: 2024 年 3 月

單元 55 - 實體屬性與方法介紹如何定義實體屬性及實體方法。

這個例子定義了三個類別,其中 DemoDemo2Demo3 的父類別, Demo3 改寫 Demodo_something() 方法,執行結果如下

> python class_demo24.py
aaa
aaa
bbb
>

如果子類別改寫父類別的方法後,仍希望使用父類別方法的定義,那就要用內建函數 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
43
44
45
46
# 定義父類別
class Demo:
    # 定義父類別的建構子
    def __init__(self, p):
        self.a = p
        self.__b = 13

    # 定義父類別的字串表達方式
    def __str__(self):
        return "Demo"

    # 定義父類別的方法
    def do_something(self):
        return self.__b

# 定義子類別
class Demo2(Demo):
    # 定義子類別的建構子
    def __init__(self, p1, p2):
        # 呼叫父類別的建構子
        super().__init__(p1)
        # 設定子類別的屬性
        self.b = p2

    # 定義子類別的字串表達方式
    def __str__(self):
        # 加上父類別的字串表達方式
        return super().__str__() + "2"

    # 改寫父類別的方法
    def do_something(self):
        # 呼叫父類別的方法
        return super().do_something()

# 執行部分
d = Demo2(11, 12)
print(d)
print(d.a)
print(d.b)
print(d.do_something())

# 檔名: class_demo25.py
# 說明: 《Python簡易手冊》的範例
# 網址: http://kaiching.org
# 作者: Kaiching Chang
# 時間: 2024 年 3 月

單元 56 - 建構子與解構子介紹如何定義建構子。

這個例子中,由於父類別有屬性需要透過參數設定,因此由 super() 呼叫父類別的 __init__() 來設定

18
19
20
21
22
23
    # 定義子類別的建構子
    def __init__(self, p1, p2):
        # 呼叫父類別的建構子
        super().__init__(p1)
        # 設定子類別的屬性
        self.b = p2

字串 (string) 方法是用父類別的字串方法加上子類別的指定字串

25
26
27
28
    # 定義子類別的字串表達方式
    def __str__(self):
        # 加上父類別的字串表達方式
        return super().__str__() + "2"

do_something() 則是直接回傳父類別的 do_somthing() ,由於父類別的 do_somthing() 回傳封裝屬性 __b ,因此這裡也是取得這個屬性值

30
31
32
33
    # 改寫父類別的方法
    def do_something(self):
        # 呼叫父類別的方法
        return super().do_something()

注意,子類別不能直接使用父類別封裝過的屬性或方法,但是可以透過父類別公開的方法來存取,此例執行結果如下

> python class_demo25.py
Demo2
11
12
13
>

參考資料

上一頁 單元 61 - 封裝
回 Python 簡易手冊 首頁
下一頁 單元 63 - 多重繼承
回 Python 教材首頁
回程式語言教材首頁