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

面向物件--多型

多型

所謂多型:定義時的型別和執行時的型別不一樣,此時就成為多型 ,多型的概念是應用於Java和C#這一類強型別語言中,而Python崇尚“鴨子型別”。

鴨子型別:雖然我想要一隻"鴨子",但是你給了我一隻鳥。 但是隻要這隻鳥走路像鴨子,叫起來像鴨子,游泳也像鴨子,我就認為這是鴨子。

Python的多型,就是弱化型別,重點在於物件引數是否有指定的屬性和方法,如果有就認定合適,而不關心物件的型別是否正確。

  • Python虛擬碼實現Java或C#的多型

class F1(object):
    def show(self):
        print('F1.show')

class S1(F1):
    def show(self):
        print('S1.show')

class S2(F1):
    def show(self):
        print('S2.show')

# 由於在Java或C#中定義函式引數時,必須指定引數的型別
# 為了讓Func函式既可以執行S1物件的show方法,又可以執行S2物件的show方法,
# 所以在def Func的形參中obj的型別是 S1和S2的父類即F1
# 
# 而實際傳入的引數是:S1物件和S2物件

def Func(F1 obj): 
    """Func函式需要接收一個F1型別或者F1子類的型別"""

    print(obj.show())

s1_obj = S1()
Func(s1_obj) # 在Func函式中傳入S1類的物件 s1_obj,執行 S1 的show方法,結果:S1.show

s2_obj = S2()
Func(s2_obj) # 在Func函式中傳入Ss類的物件 ss_obj,執行 Ss 的show方法,結果:S2.show

通俗點理解:定義obj這個變數是說的型別是:F1的型別,但是在真正呼叫Func函式時給其傳遞的不一定是F1類的例項物件,有可能是其子類的例項物件, 這種情況就是所謂的多型

  • Python “鴨子型別”
class F1(object):
    def show(self):
        print('F1.show')

class S1(F1):
    def show(self):
        print('S1.show')

class S2(F1):
    def show(self):
        print('S2.show')

def Func(obj):  
    # python是弱型別,即無論傳遞過來的是什麼,obj變數都能夠指向它,這也就沒有所謂的多型了(弱化了這個概念)
    print(obj.show())

s1_obj = S1()
Func(s1_obj) 

s2_obj = S2()
Func(s2_obj)