Python Object-oriented Programming -3 Inheritance

Young Chen
宅男雜誌
Published in
4 min readFeb 6, 2020

再談繼承(Inheritance)

之前Overview篇談到OOP特性之一繼承中,是這麼定義:

繼承(Inheritance): 子物件可以繼承父物件的所有欄位與屬性,並且可以新增欄位或修改函數。

ummm…來個富爸爸吧?

繼承的本質是重用其他類別的方法,懶惰的工程師追求各種重用可是最高指導原則之一。那麼該如何透過繼承重用程式碼呢?

偷…懶…囉

可愛的狗狗又來了,繼續用狗舉例吧:

欸不是這個!

假設狗是動物的一種,動物與狗之間應該有些共同的特性(屬性/行為),若是物件間有is-a 關係,這時就很適合透過繼承來重用程式碼,先來定義比較抽象的動物類別吧:

class Animal():

def __init__(self):
print("Animal Created!")

def who_am_i(self):
print("I am an animal.")

def eat(self):
print("I am eating~")

這裡假設動物這類別初始化時印出Animal Created!who_am_i() 定義了動物行為會回答自己是什麼(見鬼了!)。舉例嘛,將就些。

一樣地,也定義了進食這行為,一樣印出相關字樣。接著我們來定義狗,狗是動物的一種(is-a 關係)

class Dog(Animal):

pass
my_dog = Dog()
# Animal Created!
my_dog.eat()
# I am eating~
my_dog.who_am_i()
# I am an animal.

要有繼承的效果,在Python中是把父類別Animal作為子類別Dog參數,如Dog(Animal) 。上面程式碼段落定義的類別Dog即使什麼不做,也繼承了Animal的__init__() ,當Dog instance my_dog被建立時,印出了訊息 Animal Created!

當然,所有的method也依然會被繼承,因此呼叫my_dog.eat(), my_dog.who_am_i() 都是可行的。不過這邊開始覺得哪裡怪怪的,這隻狗覺得自己是動物這麼抽象的概念?能不能用一樣方法,讓進食eat()這行為有點狗的概念?

來改寫一下eat() 吧!

Override — 覆寫父類別的方法(method)

真實狀況是時常需要重用父類別的某些行為,但又需要與父類別的不一樣。延續狗的例子,來嘗試重用eat() 並且擁有自己狗特性:

class Dog(Animal):

def __init__(self):
Animal.__init__(self)
print("Dog Created!")

def eat(self): # override Animal.eat()
print("Dog is eating~")

重新初始化後:

my_dog = Dog()
my_dog.eat()
# Animal Created!
# Dog Created!
# Dog is eating~

以上程式碼觀察到,透過eat() 透過覆寫的技巧成為狗特定的訊息。此外亦可發現,有別於eat()的完全覆寫,__init__() 方法中保留了Animal特性並且又多了狗的特定訊息,端看需求需要怎樣的技巧。

--

--

Young Chen
宅男雜誌

曾經是全端工程師,目前在資料科學團隊中主要負責雲端架構相關工作,透過自學正在資料科學領域相關知識耕耘中。mail: chiyoung0307@gmail.com