1. 程式人生 > 實用技巧 >多型、多型性和鴨子型別

多型、多型性和鴨子型別

目錄


多型

多型指的是同一種事物有多種形態,比如水有液態、固態和氣態。

一個抽象類有多個子類,因而多型的概念依賴於繼承。

class Animal:
    def talk(self):
        pass

class Dog(Animal):
    def talk(self):
        print('汪汪汪')

class Cat(Animal):
    def talk(self):
        print('喵喵喵')

class Pig(Animal):
    def talk(self):
        print('哼哼哼')


dog = Dog()
cat = Cat()
pig = Pig()

多型性

多型性指的是可以在不用考慮物件具體型別的情況下而直接使用物件,這就需要在設計時,把物件的使用方法統一成一種:例如cat、dog、pig都是動物,但凡是動物肯定有talk方法,於是我們可以不用考慮它們三者的具體是什麼型別的動物,而直接使用

dog.talk()
cat.talk()
pig.talk()

汪汪汪
喵喵喵
哼哼哼

更進一步,可以定義一個統一的介面來呼叫:

def Talk(obj):
    obj.talk()

Talk(dog)
Talk(cat)
Talk(pig)

Python中的內建型別本身就支援多型性:

# 可以在不考慮型別的情況下使用同樣的方法。
'str'.__len__()
[1,2,3].__len__()
{'k1':'v1','k2':'v2'}.__len__()

# 同樣內建了一個統一的介面
len('str')
len([1,2,3])
len({'k1':'v1','k2':'v2'})

多型性的優點:

  1. 增加了程式的靈活性:以不變應萬變,無論物件千變萬化,使用者都是同一種形式去呼叫。
  2. 增加了程式的可擴充套件性:通過繼承基類建立了新的類,使用者無需更改自己的程式碼,還是用相同的方式呼叫。

多型和多型性是不同的概念:

  • 多型:在定義角度,同一種事物的多種形態,動物分為人類,豬類。
  • 多型性:在呼叫階段,同一種呼叫方式,不同的執行效果(多型性)

鴨子型別

字面意思指的是:如果看起來像、叫聲像而且走起路來像鴨子,那麼它就是鴨子。

在程式碼中的意思是:只要類中有共同父類的屬性和方法,就認為是同一個類。鴨子型別在某種程度上實現了鬆耦合度。

class Person:    # Person就是鴨子
    def run(self):
        print('跑步技能')

class Coder:     # Coder就可以當成Person類
    def run(self):
        print('跑路技能')
        
    def work(self):
        print('打工技能')
        
class Driver:    # Driver也可以當成Person類
    head = 1
    def run(self):
        print('開車技能')

Coder和Driver都擁有Person類的所有屬性,即便Coder和Driver中各自又有自己的屬性,它們依然能當做Person類。這樣就可以不受父類約束從而也能達到多型性的目的。

多型必須是繼承關係,子類必須將屬性名和方法名及方法引數保持與父類一致(屬性值和方法內程式碼可以不一樣)。為了避免子類的屬性名與父類不同,所以可以用abc模組進行限制。Python並不推薦使用abc模組限制,而更推薦使用鴨子態,但鴨子態容易失誤寫錯屬性名,所以我們還可以使用拋異常的方式進行限制命名。