面向對象之多態、多態性


一 多態

多態指的是一類事物有多種形態

動物有多種形態:人,狗,豬

import abc
class Animal(metaclass=abc.ABCMeta): #同一類事物:動物
    @abc.abstractmethod
    def talk(self):
        pass

class People(Animal): #動物的形態之一:人
    def talk(self):
        print('say hello')

class Dog(Animal): #動物的形態之二:狗
    def talk(self):
        print('say wangwang')

class Pig(Animal): #動物的形態之三:豬
    def talk(self):
        print('say aoao')

 

文件有多種形態:文本文件,可執行文件

import abc


class File(metaclass=abc.ABCMeta):  # 同一類事物:文件
    @abc.abstractmethod
    def click(self):
        pass


class Text(File):  # 文件的形態之一:文本文件
    def click(self):
        print('open file')


class ExeFile(File):  # 文件的形態之二:可執行文件
    def click(self):
        print('execute file')

 

二 多態性

A.  什么是多態動態綁定(在繼承的背景下使用時,有時也稱為多態性)

    多態性是指在不考慮實例類型的情況下使用實例

在面向對象方法中一般是這樣表述多態性:向不同的對象發送同一條消息(!!!obj.func():是調用了obj的方法func,又稱為向obj發送了一條消息func),不同的對象在接收時會產生不同的行為(即方法)。也就是說,每個對象可以用自己的方式去響應共同的消息。所謂消息,就是調用函數,不同的行為就是指不同的實現,即執行不同的函數。

比如:老師.下課鈴響了(),學生.下課鈴響了(),老師執行的是下班操作,學生執行的是放學操作,雖然二者消息一樣,但是執行的效果不同
View Code

 

    多態性分為靜態多態性和動態多態性

      靜態多態性:如任何類型都可以用運算符+進行運算

      動態多態性:如下

peo = People()
dog = Dog()
pig = Pig()

# peo、dog、pig都是動物,只要是動物肯定有talk方法
# 於是我們可以不用考慮它們三者的具體是什么類型,而直接使用
peo.talk()
dog.talk()
pig.talk()


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

 

B.  為什么要用多態性(多態性的好處)

    其實大家從上面多態性的例子可以看出,我們並沒有增加什么新的知識,也就是說python本身就是支持多態性的,這么做的好處是什么呢?

       1.增加了程序的靈活性

      以不變應萬變,不論對象千變萬化,使用者都是同一種形式去調用,如func(animal)

       2.增加了程序額可擴展性

      通過繼承animal類創建了一個新的類,使用者無需更改自己的代碼,還是用func(animal)去調用  

 

class Cat(Animal):  # 屬於動物的另外一種形態:貓
    def talk(self):
        print('say miao')


def func(animal):  # 對於使用者來說,自己的代碼根本無需改動
    animal.talk()


cat1 = Cat()  # 實例出一只貓
func(cat1)  # 甚至連調用方式也無需改變,就能調用貓的talk功能


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

 

三 鴨子類型

歡樂時刻:

  Python崇尚鴨子類型,即‘如果看起來像、叫聲像而且走起路來像鴨子,那么它就是鴨子’

       python程序員通常根據這種行為來編寫程序。例如,如果想編寫現有對象的自定義版本,可以繼承該對象,也可以創建一個外觀和行為像,但與它無任何關系的全新對象,后者通常用於保存程序組件的松耦合度。

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

# 二者都像鴨子,二者看起來都像文件,因而就可以當文件一樣去用
class TxtFile:
    def read(self):
        pass

    def write(self):
        pass


class DiskFile:
    def read(self):
        pass

    def write(self):
        pass
View Code

 

例2:其實大家一直在享受着多態性帶來的好處,比如Python的序列類型有多種形態:字符串,列表,元組,多態性體現如下

# str,list,tuple都是序列類型
s = str('hello')
l = list([1, 2, 3])
t = tuple((4, 5, 6))

# 我們可以在不考慮三者類型的前提下使用s,l,t
s.__len__()
l.__len__()
t.__len__()

len(s)
len(l)
len(t)
View Code

 


免責聲明!

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



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