多態的概念程序員
多態指的是一類事物的多種形態,例如水有固態、液態、氣態,動物有人、狗、豬,這是動物的不一樣形態。可能你會領悟,人狗豬不是繼承於動物類嗎?沒錯,多態在程序中的表現形式就是依賴於繼承
ide
多態性spa
那多態到底有什麼特性呢?多態性指的是能夠在不用考慮對象具體類型的前提下,直接使用對象下的方法,也就是說,繼承同一個類的多個子類有相同的方法名,那麼子類產生的對象就能夠不用考慮具體的類型而直接調用對象的方法code
舉一個例子,動物有人狗豬,動物都會叫,那麼人狗豬也都會叫,只不過叫的方式不一樣對象
class Animal: pass
class People(Animal): def speak(self): print('say hello') class Dog(Animal): def speak(self): print('汪汪汪') class Pig(Animal): def speak(self): print('哼哼哼') # peo、dog、pig都是動物, 只要是動物確定有speak方法 # 因而咱們能夠不用考慮它們三者的具體是什麼類型, 而直接使用
peo = People() dog1 = Dog() pig1 = Pig() peo.speak() dog1.speak() pig1.speak()
可是美中不足的是,若是如今人的叫不寫成 speak ,寫成 talk,那麼便沒法遵循父類的方法去實現多態性,若是這三個都想實現叫的功能,父類要有,子類也要有,這顯然很麻煩,而且這樣寫不能對子類有個強制性的限制,這個限制是子類必須有一個叫的功能,這個功能是 speak。因而要寫一個解決方案,強制子類遵循父類的標準,有一個 abc 的模塊,能夠實現這個功能blog
import abc class Animal(metaclass=abc.ABCMeta): @abc.abstractmethod def speak(self): pass
class People(Animal): # def speak(self):
# print('say hello')
# 寫成talk便會報錯
def talk(self): print('say hello') class Dog(Animal): def speak(self): print('汪汪汪') class Pig(Animal): def speak(self): print('哼哼哼') peo = People() dog1 = Dog() pig1 = Pig() peo.speak() dog1.speak() pig1.speak() # 運行
TypeError: Can't instantiate abstract class People with abstract methods speak
鴨子類型繼承
可是上面所說的這些並非 Python 所推崇的,Python 崇尚的是 「鴨子類型」 ,即 「若是看起來像鴨子、叫聲像鴨子並且走起路來也像鴨子,那麼它就是鴨子」,字符串
Python 程序員一般根據這種行爲來編寫程序。例如,若是想編寫現有對象的自定義版本,能夠繼承該對象,也能夠建立一個外觀和行爲像,但與它無任何關係的全新對象,後者一般用於保存程序組件的解耦合度it
# 利用標準庫中定義的各類‘與文件相似’的對象,儘管這些對象的工做方式像文件,但他們沒有繼承內置文件對象的方法 # 兩者都像鴨子,兩者看起來都像文件,於是就能夠當文件同樣去用
class TxtFile: def read(self): pass
def write(self): pass
class DiskFile: def read(self): pass
def write(self): pass
# 例2:其實你們一直在享受着多態性帶來的好處,好比Python的序列類型有多種形態:字符串,列表,元組,多態性體現以下 # str,list,tuple都是序列類型
s=str('hello') l=list([1,2,3]) t=tuple((4,5,6)) # 咱們能夠在不考慮三者類型的前提下使用s,l,t
s.__len__() l.__len__() t.__len__() len(s) len(l) len(t)