在面向對象編程中,接口的多種不一樣的實現方式即爲多態。多態的做用,就是爲了類在繼承和派生的時候,保證使用「家譜」中任一類的實例的某一屬性時的正確調用。python
多態的目的就是實現接口重用。編程
多態指的是一類事物有多種形態。好比動物有多種形態:人、狗、豬。ide
import abc #利用abc模塊實現抽象類 class Animal(metaclass=abc.ABCMeta): # 相似接口,只定義規範,不實現具體的代碼 @abc.abstractclassmethod def talk(self): pass class People(Animal): # 動物形態之一:人 def talk(self): print('people is talking') class Pig(Animal): # 動物形態之二:豬 def talk(self): print('Pig is talking') class Dog(Animal): # 動物形態之三:狗 def talk(self): print('Dog is talking')
多態性指在不考慮實例類型的狀況下使用實例,多態性分爲靜態多態性和動態多態性。函數
靜態多態性:就是在系統編譯期間就能夠肯定程序執行到這裏將要執行哪一個函數spa
動態多態性:則是利用虛函數實現了運行時的多態,也就是說在系統編譯的時候並不知道程序將要調用哪個函數,只有在運行到這裏的時候才能肯定接下來會跳轉到哪個函數的棧幀。以下所示:code
peo1 = People() pig1 = Pig() dog1 = Dog() # 調用方法不用考慮三者具體是什麼類型直接使用,這種就是動態多態性 # peo1.talk() # pig1.talk() # dog1.talk() #更進一步,咱們能夠定義一個統一的接口來使用 def func(animal): animal.talk() func(peo1) func(pig1) func(dog1)
由上例能夠看出,python自己就是支持多態性的。對象
(1)增長程序的靈活性blog
以不變應萬變,不管對象變幻無窮,使用者都是同一種形式去調用繼承
(2)增長程序的擴展性接口
經過繼承animal類建立一個新類,使用者能夠不改變本身的代碼,依然用func(animal)調用
>>> class Cat(Animal): #屬於動物的另一種形態:貓 ... def talk(self): ... print('say miao') ... >>> def func(animal): #對於使用者來講,本身的代碼根本無需改動 ... animal.talk() ... >>> cat1=Cat() #實例出一隻貓 >>> func(cat1) #甚至連調用方式也無需改變,就能調用貓的talk功能 say miao ''' 這樣咱們新增了一個形態Cat,由Cat類產生的實例cat1,使用者能夠在徹底不須要修改本身代碼的狀況下。
使用和人、狗、豬同樣的方式調用cat1的talk方法,即func(cat1) '''
什麼是鴨子類型(Duck Typing)?鴨子類型可解釋爲,若是一隻動物,走起來像鴨子或者叫起來像鴨子,就能夠把它看成鴨子。
python崇尚一種鴨子類型,類與類之間不用共同繼承一個父類,只須要將它們作得像一種事物便可。
例如,若是想編寫現有對象的自定義版本。
一、能夠繼承該對象
二、能夠建立一個外觀和行爲像,但與它無任何關係的全新對象(一般用於保存程序組件的鬆耦合度)
例1:利用標準庫中定義的各類‘與文件相似’的對象,儘管這些對象的工做方式像文件,但他們沒有繼承內置文件對象的方法
class File: def read(self): pass def write(self): pass class Disk: def read(self): print('disk read') def write(self): print('disk write') class Text: def read(self): print('text read') def write(self): print('text write') disk = Disk() text = Text() disk.read() disk.write() text.read() text.write() """ disk read disk write text read text write """
例2:序列類型有多種形態:字符串,列表,元組,但他們直接沒有直接的繼承關係
# 序列類型:列表list、元組tuple、字符串str l = list([1, 2, 3]) t = tuple(('a', 'b')) s = str('hello') print(l.__len__()) # 3 print(t.__len__()) # 2 print(s.__len__()) # 5