多重繼承 | Python從入門到精通:高階篇之三十二
多態
多態是面向對象的三大特徵之一。
多態從字面上理解是多種形態。例如:狗有多個種類(狼狗、藏獒、哈士奇、古代牧羊犬...)。
一個對象可以以不同的形態去呈現。
我們先來定義兩個類:
class A:
def __init__(self,name):
self._name = name
@property
def name(self):
return self._name
@name.setter
def name(self,name):
self._name = name
class B:
def __init__(self,name):
self._name = name
@property
def name(self):
return self._name
@name.setter
def name(self,name):
self._name = name
a = A('孫悟空')
b = B('豬八戒')
定義一個函數:
def say_hello(obj):
print('你好 %s'%obj.name)
# say_hello(a)
say_hello(b)
執行結果:
我們來再定義一個C類,c是否可以作為參數傳入say_hello:
class C:
pass
c = C()
say_hello(c)
執行結果:
對於say_hello()這個函數來說,只要對象中含有name屬性,它就可以作為參數傳遞,這個函數並不會考慮對象的類型,只要有name屬性即可。
我們再來定義一個沒有多態屬性的函數:
def say_hello_2(obj):
# 做類型檢查
if isinstance(obj , A):
print('你好 %s'%obj.name)
# say_hello_2(a)
say_hello_2(b)
執行結果:
在say_hello_2中我們做了一個類型檢查,也就是隻有obj是A類型的對象時,才可以正常使用,其他類型的對象都無法使用該函數,這個函數就違反了多態。違反了多態的函數,只適用於一種類型的對象,無法處理其他類型對象,這樣導致函數的適應性非常的差。
多態的描述:
鴨子類型
如果一個東西,走路像鴨子,叫聲像鴨子,那麼它就是鴨子。
我們通過一個例子來說明
len()
l = [1,2,3]
s = 'hello'
print(len(l))
print(len(s))
執行結果:
之所以一個對象能通過len()來獲取長度,是因為對象中具有一個特殊方法__len__。
換句話說,只要對象中具有__len__特殊方法,就可以通過len()來獲取它的長度。
我們在B中定義一個len()
def __len__(self):
return 10
print(len(b))
print(len(c))
執行結果:
B中有len()方法,所以有返回值,但是C中沒有,所以程序出錯。
注意,像isinstance()這種函數,在開發中一般是不會使用的!可能違反多態。
我們總結一下面向對象的三大特徵:
封裝
- 確保對象中的數據安全
繼承
- 保證了對象的可擴展性
多態
- 保證了程序的靈活性
配套視頻課程,點擊這裡查看
獲取更多資源請訂閱Python學習站