開發與維運

多態簡介 | Python從入門到精通:高階篇之三十三

多重繼承 | 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) 

執行結果:

image.pngimage.png

我們來再定義一個C類,c是否可以作為參數傳入say_hello:

class C:
    pass

c = C()
say_hello(c) 

執行結果:

image.png

對於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)

執行結果:

image.png
image.png

在say_hello_2中我們做了一個類型檢查,也就是隻有obj是A類型的對象時,才可以正常使用,其他類型的對象都無法使用該函數,這個函數就違反了多態。違反了多態的函數,只適用於一種類型的對象,無法處理其他類型對象,這樣導致函數的適應性非常的差。

多態的描述:
鴨子類型
如果一個東西,走路像鴨子,叫聲像鴨子,那麼它就是鴨子。

我們通過一個例子來說明
len()

l = [1,2,3]
s = 'hello'

print(len(l))
print(len(s))

執行結果:

image.png

之所以一個對象能通過len()來獲取長度,是因為對象中具有一個特殊方法__len__。
換句話說,只要對象中具有__len__特殊方法,就可以通過len()來獲取它的長度。
我們在B中定義一個len()

 def __len__(self):
        return 10

print(len(b))
print(len(c))

執行結果:

image.png

B中有len()方法,所以有返回值,但是C中沒有,所以程序出錯。

注意,像isinstance()這種函數,在開發中一般是不會使用的!可能違反多態。

我們總結一下面向對象的三大特徵:
封裝

  • 確保對象中的數據安全

繼承

  • 保證了對象的可擴展性

多態

  • 保證了程序的靈活性

配套視頻課程,點擊這裡查看

獲取更多資源請訂閱Python學習站

Leave a Reply

Your email address will not be published. Required fields are marked *