|
要理解什么是多態(tài),我們首先要對數(shù)據(jù)類型再作一點說明。當我們定義一個class的時候,我們實際上就定義了一種數(shù)據(jù)類型。我們定義的數(shù)據(jù)類型和Python自帶的數(shù)據(jù)類型,比如str、list、dict沒什么兩樣: a = list() # a是list類型 b = Animal() # b是Animal類型 c = Dog() # c是Dog類型 判斷一個變量是否是某個類型可以用isinstance()判斷: >>> isinstance(a, list) True >>> isinstance(b, Animal) True >>> isinstance(c, Dog) True 看來a、b、c確實對應著list、Animal、Dog這3種類型。 但是等等,試試: >>> isinstance(c, Animal) True 看來c不僅僅是Dog,c還是Animal! 不過仔細想想,這是有道理的,因為Dog是從Animal繼承下來的,當我們創(chuàng)建了一個Dog的實例c時,我們認為c的數(shù)據(jù)類型是Dog沒錯,但c同時也是Animal也沒錯,Dog本來就是Animal的一種! 所以,在繼承關系中,如果一個實例的數(shù)據(jù)類型是某個子類,那它的數(shù)據(jù)類型也可以被看做是父類。但是,反過來就不行: >>> b = Animal() >>> isinstance(b, Dog) False Dog可以看成Animal,但Animal不可以看成Dog。 要理解多態(tài)的好處,我們還需要再編寫一個函數(shù),這個函數(shù)接受一個Animal類型的變量: def run_twice(animal): animal.run() animal.run() 當我們傳入Animal的實例時,run_twice()就打印出: >>> run_twice(Animal()) Animal is running... Animal is running... 當我們傳入Dog的實例時,run_twice()就打印出: >>> run_twice(Dog()) Dog is running... Dog is running... 當我們傳入Cat的實例時,run_twice()就打印出: >>> run_twice(Cat()) Cat is running... Cat is running... 看上去沒啥意思,但是仔細想想,現(xiàn)在,如果我們再定義一個Tortoise類型,也從Animal派生: class Tortoise(Animal): def run(self): print('Tortoise is running slowly...') 當我們調(diào)用run_twice()時,傳入Tortoise的實例: >>> run_twice(Tortoise()) Tortoise is running slowly... Tortoise is running slowly... 你會發(fā)現(xiàn),新增一個Animal的子類,不必對run_twice()做任何修改,實際上,任何依賴Animal作為參數(shù)的函數(shù)或者方法都可以不加修改地正常運行,原因就在于多態(tài)。 多態(tài)的好處就是,當我們需要傳入Dog、Cat、Tortoise……時,我們只需要接收Animal類型就可以了,因為Dog、Cat、Tortoise……都是Animal類型,然后,按照Animal類型進行操作即可。由于Animal類型有run()方法,因此,傳入的任意類型,只要是Animal類或者子類,就會自動調(diào)用實際類型的run()方法,這就是多態(tài)的意思: 對于一個變量,我們只需要知道它是Animal類型,無需確切地知道它的子類型,就可以放心地調(diào)用run()方法,而具體調(diào)用的run()方法是作用在Animal、Dog、Cat還是Tortoise對象上,由運行時該對象的確切類型決定,這就是多態(tài)真正的威力:調(diào)用方只管調(diào)用,不管細節(jié),而當我們新增一種Animal的子類時,只要確保run()方法編寫正確,不用管原來的代碼是如何調(diào)用的。這就是著名的“開閉”原則: 對擴展開放:允許新增Animal子類; 對修改封閉:不需要修改依賴Animal類型的run_twice()等函數(shù)。 繼承還可以一級一級地繼承下來,就好比從爺爺?shù)桨职?、再到兒子這樣的關系。而任何類,最終都可以追溯到根類object,這些繼承關系看上去就像一顆倒著的樹。比如如下的繼承樹: ┌───────────────┐ │ object │ └───────────────┘ │ ┌────────────┴────────────┐ │ │ ▼ ▼ ┌─────────────┐ ┌─────────────┐ │ Animal │ │ Plant │ └─────────────┘ └─────────────┘ │ │ ┌─────┴──────┐ ┌─────┴──────┐ │ │ │ │ ▼ ▼ ▼ ▼ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ Dog │ │ Cat │ │ Tree │ │ Flower │ 分享知識,分享快樂!希望中國站在編程之巔!
360圖書館館號:rsgz002.360doc.com |
|
|