1. 程式人生 > 實用技巧 >面向物件之多型

面向物件之多型

多型的介紹

多型指的是一類事物有多種形態,比如動物有多種形態:貓、狗、豬

class Animal:  # 統一所有子類的方法
    def say(self):
        print('動物基本的發聲...')


class People(Animal):
    def say(self):
        super(People, self).say()
        print('嚶嚶嚶')


class Dog(Animal):
    def say(self):
        super(Dog, self).say()
        print('汪汪汪'
) class Pig(Animal): def say(self): super(Pig, self).say() print('哼哼哼') obj1 = Animal() obj2 = Dog() obj3 = Pig()

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

# 定義統一的介面, 接收傳入的動物物件
def animal_say(animal):
    animal.say()


animal_say(obj1)
animal_say(obj2)
animal_say(obj3)

鴨子型別

其實我們完全可以不依賴於繼承,只需要製造出外觀和行為相同物件,同樣可以實現不考慮物件型別而使用物件,這正是Python崇尚的“鴨子型別”(duck typing):“如果看起來像、叫聲像而且走起路來像鴨子,那麼它就是鴨子”。比起繼承的方式,鴨子型別在某種程度上實現了程式的鬆耦合度,如下

# 二者看起來都像檔案,因而就可以當檔案一樣去用,然而它們並沒有直接的關係
class Txt:  # Txt類有兩個與檔案型別同名的方法,即read和write
    def read(self):
        pass

    def
write(self): pass class Disk: # Disk類也有兩個與檔案型別同名的方法:read和write def read(self): pass def write(self): pass

抽象類

多型性的本質在於不同的類中定義有相同的方法名,這樣我們就可以不考慮類而統一用一種方式去使用物件,可以通過在父類引入抽象類的概念來硬性限制子類必須有某些方法名

import abc


#
抽象化父類 # 指定metaclass屬性將類設定為抽象類,抽象類本身只是用來約束子類的,不能被例項化 class Animal(metaclass=abc.ABCMeta): @abc.abstractmethod # 該裝飾器限制子類必須定義有一個名為talk的方法 def talk(self): # 抽象方法中無需實現具體的功能 pass class Cat(Animal): # 但凡繼承Animal的子類都必須遵循Animal規定的標準 def talk(self): pass obj = Animal() # 不能例項化抽象類自己 cat = Cat() # 若子類中沒有一個名為talk的方法則會丟擲異常TypeError,無法例項化