面向?qū)ο蟮娜蟾拍?,多態(tài)。
多態(tài):同一操作作用于不同的對(duì)象,可以有不同的解釋?zhuān)a(chǎn)生不同的執(zhí)行結(jié)果。
多態(tài)主要是針對(duì)繼承來(lái)說(shuō)的。
多個(gè)子類(lèi)繼承父類(lèi)的屬性和方法,子類(lèi)也可以重寫(xiě)這些方法。當(dāng)不同的子類(lèi)重寫(xiě)同一個(gè)方法時(shí),這個(gè)方法在不同的子類(lèi)中就具有了不同的功能。
那么從這些子類(lèi)中實(shí)例化出來(lái)的多個(gè)對(duì)象,分別調(diào)用該方法時(shí),就會(huì)產(chǎn)生不同的結(jié)果。(這是當(dāng)然的,每個(gè)子類(lèi)都重寫(xiě)了該方法嘛。)
當(dāng)我們不管子類(lèi)重寫(xiě)的具體功能,直接用該方法寫(xiě)一個(gè)各個(gè)子類(lèi)都通用的函數(shù)。
比如,我們重新定義一下人類(lèi)類(lèi),人類(lèi)都需要工作 work(),但是不同的職業(yè)工作類(lèi)型不同,比如學(xué)生的 work() 應(yīng)該是學(xué)習(xí)、司機(jī)的 work() 應(yīng)該是開(kāi)車(chē)、教師的工作是講課等等。
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def work(self):
# 人類(lèi)有工作,但是不同的職業(yè)工作不同
# 使用 pass 占位咯
pass
# 學(xué)生類(lèi)繼承自人類(lèi)
class Student(Person):
def work(self):
return '%s 的工作是學(xué)習(xí)...' % self.name
# 司機(jī)類(lèi)繼承自人類(lèi)
class Driver(Person):
def work(self):
return '%s 的工作是開(kāi)車(chē)...' % self.name
# 教師類(lèi)繼承自人類(lèi)
class Teacher(Person):
def work(self):
return '%s 的工作是講課...' % self.name
通過(guò)以上代碼,我們實(shí)現(xiàn)了一個(gè)父類(lèi) Person, 三個(gè)子類(lèi)。
我們寫(xiě)一個(gè)函數(shù),暫時(shí)每個(gè)人的工作:
def show_work(obj):
print(obj.work())
注意obj.work(), obj 可以是任意類(lèi)型的對(duì)象,只要這個(gè)對(duì)象具備 work() 這個(gè)方法,這個(gè)函數(shù)就可以正常運(yùn)行。
這也就是我們所謂的寫(xiě)一個(gè)通用的函數(shù),不管你的對(duì)象是 Student、Driver、Teacher,都可以。
接下來(lái)我們使用這個(gè)函數(shù):
s = Student('小明', 11)
show_work(s)
# 小明 的工作是學(xué)習(xí)...
t = Teacher('老張', 33)
show_work(t)
# 老張 的工作是講課...
我們可以看到 show_work() 函數(shù)對(duì)于這些類(lèi)的對(duì)象都可以使用。也就是同一操作作用于不同的對(duì)象,可以有不同的解釋?zhuān)a(chǎn)生不同的執(zhí)行結(jié)果。
當(dāng)然其實(shí) Python 這種動(dòng)態(tài)語(yǔ)言多態(tài)沒(méi)什么好談的,因?yàn)閯?dòng)態(tài)語(yǔ)言的變量都沒(méi)有指定類(lèi)型。所以本身就只在乎變量(對(duì)象)擁有的屬性和方法,并不關(guān)注到底是什么類(lèi)型。
比如下面的例子,我們寫(xiě)一個(gè)加法函數(shù),簡(jiǎn)單的打印參數(shù) a+b 的結(jié)果。
def add(a, b):
print(a+b)
我們可以看到 a, b 參數(shù)沒(méi)有限制任何類(lèi)型。那么只要支持加法的類(lèi)型,其實(shí)都可以使用該函數(shù)完成相加的操作。那么支持加法操作的類(lèi)型有哪些呢?數(shù)值類(lèi)型、字符串、列表、元組,都支持相加。
>>> add(5, 6)
11
>>> add('你', '好')
你好
>>> add([1,2,3], ['a','b','c'])
[1, 2, 3, 'a', 'b', 'c']
>>> add((5,6), (7,8))
(5, 6, 7, 8)
也就是,根本不 care 你的類(lèi)型。
這也就是大家所耳熟能詳?shù)?code>鴨子類(lèi)型。
一只鳥(niǎo)長(zhǎng)得像鴨子,叫聲像鴨子,走路也像鴨子,那它就是鴨子。
作為鴨子類(lèi)型語(yǔ)言,我們不關(guān)心對(duì)象的類(lèi)型,只關(guān)注這個(gè)對(duì)象的行為和特征。
所以你可以認(rèn)為 Python 天然多態(tài)。