面向對象三大特性——多態(含鴨子類型)


一、多態概念

  在面向對象編程中,接口的多種不同的實現方式即為多態。多態的作用,就是為了類在繼承和派生的時候,保證使用“家譜”中任一類的實例的某一屬性時的正確調用。

二、多態目的

  多態的目的就是實現接口重用

  多態指的是一類事物有多種形態。比如動物有多種形態:人、狗、豬。

import abc    #利用abc模塊實現抽象類
class Animal(metaclass=abc.ABCMeta):  # 類似接口,只定義規范,不實現具體的代碼
    @abc.abstractclassmethod
    def talk(self):
        pass

class People(Animal):  # 動物形態之一:人
    def talk(self):
        print('people is talking')

class Pig(Animal):     # 動物形態之二:豬
    def talk(self):
        print('Pig is talking')

class Dog(Animal):     # 動物形態之三:狗
    def talk(self):
        print('Dog is talking')

三、多態性

1、多態性概念

  多態性指在不考慮實例類型的情況下使用實例,多態性分為靜態多態性和動態多態性。

  靜態多態性:就是在系統編譯期間就可以確定程序執行到這里將要執行哪個函數

  動態多態性:則是利用虛函數實現了運行時的多態,也就是說在系統編譯的時候並不知道程序將要調用哪一個函數,只有在運行到這里的時候才能確定接下來會跳轉到哪一個函數的棧幀。如下所示:

peo1 = People()
pig1 = Pig()
dog1 = Dog()
# 調用方法不用考慮三者具體是什么類型直接使用,這種就是動態多態性

# peo1.talk()
# pig1.talk()
# dog1.talk()


#更進一步,我們可以定義一個統一的接口來使用
def func(animal):
    animal.talk()

func(peo1)
func(pig1)
func(dog1)

  由上例可以看出,python本身就是支持多態性的。

2、多態性的好處

(1)增加程序的靈活性

      以不變應萬變,無論對象千變萬化,使用者都是同一種形式去調用

(2)增加程序的擴展性

      通過繼承animal類創建一個新類,使用者可以不改變自己的代碼,依然用func(animal)調用

>>> class Cat(Animal): #屬於動物的另外一種形態:貓
...     def talk(self):
...         print('say miao')
... 
>>> def func(animal): #對於使用者來說,自己的代碼根本無需改動
...     animal.talk()
... 
>>> cat1=Cat() #實例出一只貓
>>> func(cat1) #甚至連調用方式也無需改變,就能調用貓的talk功能
say miao

'''
這樣我們新增了一個形態Cat,由Cat類產生的實例cat1,使用者可以在完全不需要修改自己代碼的情況下。
使用和人、狗、豬一樣的方式調用cat1的talk方法,即func(cat1)
'''

四、鴨子類型

  什么是鴨子類型(Duck Typing)?鴨子類型可解釋為,如果一只動物,走起來像鴨子或者叫起來像鴨子,就可以把它當作鴨子。

  python崇尚一種鴨子類型,類與類之間不用共同繼承一個父類,只需要將它們做得像一種事物即可。

例如,如果想編寫現有對象的自定義版本。

  1、可以繼承該對象

  2、可以創建一個外觀和行為像,但與它無任何關系的全新對象(通常用於保存程序組件的松耦合度)

例1:利用標准庫中定義的各種‘與文件類似’的對象,盡管這些對象的工作方式像文件,但他們沒有繼承內置文件對象的方法

class File:
    def read(self):
        pass

    def write(self):
        pass

class Disk:
    def read(self):
        print('disk read')

    def write(self):
        print('disk write')

class Text:
    def read(self):
        print('text read')

    def write(self):
        print('text write')


disk = Disk()
text = Text()

disk.read()
disk.write()

text.read()
text.write()
"""
disk read
disk write
text read
text write
"""
像文件的類

例2:序列類型有多種形態:字符串,列表,元組,但他們直接沒有直接的繼承關系

# 序列類型:列表list、元組tuple、字符串str
l = list([1, 2, 3])
t = tuple(('a', 'b'))
s = str('hello')

print(l.__len__())  # 3
print(t.__len__())  # 2
print(s.__len__())  # 5
像序列的類型

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM