Python 繼承機制及其使用

Python 類的封裝、繼承、多態 3 大特性,前面章節已經詳細介紹了 Python 類的封裝,本節繼續講解 Python 類的繼承機制。

繼承機制經常用於創建和現有類功能類似的新類,又或是新類只需要在現有類基礎上添加一些成員(屬性和方法),但又不想直接將現有類代碼複製給新類。也就是說,通過使用繼承這種機制,可以輕鬆實現類的重複使用。

舉個例子,假設現有一個 Shape 類,該類的 draw() 方法可以在屏幕上畫出指定的形狀,現在需要創建一個 Form 類,要求此類不但可以在屏幕上畫出指定的形狀,還可以計算出所畫形狀的面積。要創建這樣的類,笨方法是將 draw() 方法直接複製到新類中,並添加計算面積的方法。實現代碼如下所示:

當然還有更簡單的方法,就是使用類的繼承機制。實現方法爲:讓 From 類繼承 Shape 類,這樣當 From 類對象調用 draw() 方法時,Python 解釋器會先去 From 中找以 draw 爲名的方法,如果找不到,它還會自動去 Shape 類中找。如此,我們只需在 From 類中添加計算面積的方法即可,示例代碼如下:

class Shape:
def draw(self,content):
        print("畫",content)
class Form(Shape):
def area(self):
#....
        print("此圖形的面積爲...")

Python 中,實現繼承的類稱爲子類,被繼承的類稱爲父類(也可稱爲基類、超類)。因此在上面這個樣例中,From 是子類,Shape 是父類。

子類繼承父類時,只需在定義子類時,將父類(可以是多個)放在子類之後的圓括號裏即可。語法格式如下:

class 類名 (父類 1, 父類 2, ...):
    #類定義部分

注意,如果該類沒有顯式指定繼承自哪個類,則默認繼承 object 類(object 類是 Python 中所有類的父類,即要麼是直接父類,要麼是間接父類)。另外,Python 的繼承是多繼承機制(和 C++ 一樣),即一個子類可以同時擁有多個直接父類。

注意,有讀者可能還聽說過 “派生” 這個詞彙,它和繼承是一個意思,只是觀察角度不同而已。換句話話,繼承是相對子類來說的,即子類繼承自父類;而派生是相對於父類來說的,即父類派生出子類。

瞭解了繼承機制的含義和語法之後,下面代碼演示了繼承機制的用法:

class People:
def say(self):
        print("我是一個人,名字是:",self.name)
class Animal:
def display(self):
        print("人也是高級動物")
#同時繼承 People 和 Animal 類
#其同時擁有 name 屬性、say() 和 display() 方法
class Person(People, Animal):
pass
zhangsan = Person()
zhangsan.name = "張三"
zhangsan.say()
zhangsan.display()

運行結果,結果爲:

我是一個人,名字是:張三
人也是高級動物

可以看到,雖然 Person 類爲空類,但由於其繼承自 People 和 Animal 這 2 個類,因此實際上 Person 並不空,它同時擁有這 2 個類所有的屬性和方法。

沒錯,子類擁有父類所有的屬性和方法,即便該屬性或方法是私有(private)的。至於爲什麼,可閱讀《Python 封裝實現原理》一節。

關於 Python 的多繼承

事實上,大部分面向對象的編程語言,都只支持單繼承,即子類有且只能有一個父類。而 Python 卻支持多繼承(C++ 也支持多繼承)。
和單繼承相比,多繼承容易讓代碼邏輯複雜、思路混亂,一直備受爭議,中小型項目中較少使用,後來的 Java、C#、PHP 等乾脆取消了多繼承。

使用多繼承經常需要面臨的問題是,多個父類中包含同名的類方法。對於這種情況,Python 的處置措施是:根據子類繼承多個父類時這些父類的前後次序決定,即排在前面父類中的類方法會覆蓋排在後面父類中的同名類方法。

舉個例子:

程序運行結果爲:

People 類 張三

可以看到,當 Person 同時繼承 People 類和 Animal 類時,People 類在前,因此如果 People 和 Animal 擁有同名的類方法,實際調用的是 People 類中的。

聲明:

本文於網絡整理,版權歸原作者所有,如來源信息有誤或侵犯權益,請聯繫我們刪除或授權事宜。

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/qwyVefqAqYyfQgOFBVjy3Q