Python Object-oriented Programming -3 Inheritance
再談繼承(Inheritance)
之前Overview篇談到OOP特性之一繼承中,是這麼定義:
繼承(Inheritance): 子物件可以繼承父物件的所有欄位與屬性,並且可以新增欄位或修改函數。
繼承的本質是重用其他類別的方法,懶惰的工程師追求各種重用可是最高指導原則之一。那麼該如何透過繼承重用程式碼呢?
可愛的狗狗又來了,繼續用狗舉例吧:
假設狗是動物的一種,動物與狗之間應該有些共同的特性(屬性/行為),若是物件間有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):
passmy_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特性並且又多了狗的特定訊息,端看需求需要怎樣的技巧。