Python的面向?qū)ο缶幊趟枷?/h2>

什么是Python的多態(tài)?
多態(tài)的好處就是,當(dāng)我們需要傳入Dog、Cat、Tortoise……時,我們只需要接收Animal類型就可以了,因為Dog、Cat、Tortoise……都是Animal類型,然后,按照Animal類型進行操作即可。由于Animal類型有run()方法,因此,傳入的任意類型,只要是Animal類或者子類,就會自動調(diào)用實際類型的run()方法,這就是多態(tài)的意思:

對于一個變量,我們只需要知道它是Animal類型,無需確切地知道它的子類型,就可以放心地調(diào)用run()方法,而具體調(diào)用的run()方法是作用在Animal、Dog、Cat還是Tortoise對象上,由運行時該對象的確切類型決定,這就是多態(tài)真正的威力:調(diào)用方只管調(diào)用,不管細(xì)節(jié),而當(dāng)我們新增一種Animal的子類時,只要確保run()方法編寫正確,不用管原來的代碼是如何調(diào)用的。這就是著名的“開閉”原則:

對擴展開放:允許新增Animal子類;

對修改封閉:不需要修改依賴Animal類型的run_twice()等函數(shù)。

[Reference]http://www.liaoxuefeng.com/wiki/001374738125095c955c1e6d8bb493182103fac9270762a000/001386820044406b227b3e751cc4d5190420d17a2dc6353000

======================
多態(tài)即多種形態(tài),在運行時確定其狀態(tài),在編譯階段無法確定其類型,這就是多態(tài)。Python中的多態(tài)和Java以及C++中的多態(tài)有點不同,Python中的變量是弱類型的,在定義時不用指明其類型,它會根據(jù)需要在運行時確定變量的類型(個人覺得這也是多態(tài)的一種體現(xiàn)),并且Python本身是一種解釋性語言,不進行預(yù)編譯,因此它就只在運行時確定其狀態(tài),故也有人說Python是一種多態(tài)語言。在Python中很多地方都可以體現(xiàn)多態(tài)的特性,比如內(nèi)置函數(shù)len(object),len函數(shù)不僅可以計算字符串的長度,還可以計算列表、元組等對象中的數(shù)據(jù)個數(shù),這里在運行時通過參數(shù)類型確定其具體的計算過程,正是多態(tài)的一種體現(xiàn)。這有點類似于函數(shù)重載(一個編譯單元中有多個同名函數(shù),但參數(shù)不同),相當(dāng)于為每種類型都定義了一個len函數(shù)。這是典型的多態(tài)表現(xiàn)。有些朋友提出Python不支持多態(tài),我是完全不贊同的。   本質(zhì)上,多態(tài)意味著可以對不同的對象使用同樣的操作,但它們可能會以多種形態(tài)呈現(xiàn)出結(jié)果。len(object)函數(shù)就體現(xiàn)了這一點。在C++、Java、C#這種編譯型語言中,由于有編譯過程,因此就鮮明地分成了運行時多態(tài)和編譯時多態(tài)。運行時多態(tài)是指允許父類指針或名稱來引用子類對象,或?qū)ο蠓椒?,而實際調(diào)用的方法為對象的類類型方法,這就是所謂的動態(tài)綁定。編譯時多態(tài)有模板或范型、方法重載(overload)、方法重寫(override)等。而Python是動態(tài)語言,動態(tài)地確定類型信息恰恰體現(xiàn)了多態(tài)的特征。在Python中,任何不知道對象到底是什么類型,但又需要對象做點什么的時候,都會用到多態(tài)。

  1. 有一種稱為”鴨子類型(duck typing)“的東西,講的也是多態(tài):
 _metaclass_=type # 確定使用新式類  
class Duck:  
    def quack(self):   
        print "Quaaaaaack!"  
    def feathers(self):   
        print "The duck has white and gray feathers."  

class Person:  
    def quack(self):  
        print "The person imitates a duck."  
    def feathers(self):   
        print "The person takes a feather from the ground and shows it."  

def in_the_forest(duck):  
    duck.quack()  
    duck.feathers()  

def game():  
    donald = Duck()  
    john = Person()  
    in_the_forest(donald)  
    in_the_forest(john)  

game()

就in_the_forest函數(shù)而言,參數(shù)對象是一個鴨子類型,它實現(xiàn)了方法多態(tài)。但是實際上我們知道,從嚴(yán)格的抽象來講,Person類型和Duck完全風(fēng)馬牛不相及。

  1. 運算符多態(tài)
  def add(x,y):  
    return x+y  

print add(1,2) #輸出3  

print add("hello,","world") #輸出hello,world  

print add(1,"abc") #拋出異常 TypeError: unsupported operand type(s) for +: 'int' and 'str'

Python的加法運算符是”多態(tài)“的,理論上,我們實現(xiàn)的add方法支持任意支持加法的對象,但是我們不用關(guān)心兩個參數(shù)x和y具體是什么類型。

  1. Python同樣支持運算符重載
 class Vector:  
   def __init__(self, a, b):  
      self.a = a  
      self.b = b  

   def __str__(self):  
      return 'Vector (%d, %d)' % (self.a, self.b)  

   def __add__(self,other):  
      return Vector(self.a + other.a, self.b + other.b)  

v1 = Vector(2,10)  
v2 = Vector(5,-2)  
print v1 + v2

在C++, Java, C#中實現(xiàn)多態(tài)的方式通常有重寫和重載兩種,從上面兩段代碼,我們其實可以分析得出Python中實現(xiàn)多態(tài)也可以變相理解為重寫和重載。在Python中很多內(nèi)置函數(shù)和運算符都是多態(tài)的。
[Reference]https://vancele.gitbooks.io/python/content/chapter7.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 面向?qū)ο蟮木幊趟枷氲陌l(fā)展歷程 我理解的面向過程與面向?qū)ο?自從學(xué)習(xí)python以來,以前所接觸的代碼是根據(jù)實際的案...
    盧子野閱讀 3,382評論 0 0
  • # 第一優(yōu)先級規(guī)則聲明: # 除了夢境,每一個意識主進程都必須與一個身體參與的機械進程相匹配,否則結(jié)束意識主進程。...
    李洞BarryLi閱讀 4,202評論 0 1
  • 1.1面向?qū)ο?面向?qū)ο?object-oriented ;簡稱: OO)至今還沒有統(tǒng)一的概念 我這里把它定義為:...
    TENG書閱讀 639評論 0 0
  • 面向?qū)ο缶幊?面向?qū)ο缶幊獭狾bject Oriented Programming,簡稱OOP,是一種程序設(shè)計思...
    時間之友閱讀 849評論 0 0
  • 進入孕晚期,體重正式增長了20斤。即使生個6斤的娃娃,加上羊水什么的,算12斤好了,還有8斤是我自己身上的肉。。。...
    釋放自我閱讀 244評論 0 1

友情鏈接更多精彩內(nèi)容