面向?qū)ο蟮木幊蹋∣bject-Oriented Programming ,OOP),每當(dāng)看到這個(gè)術(shù)語(yǔ),我們就會(huì)把它與Java聯(lián)系起來(lái)。
事實(shí)上,Java普及了面向?qū)ο蟮木幊田L(fēng)格,除了Java之外,還有很多OOP語(yǔ)言,例如,C++、C#、Swift、JavaScript、php等,當(dāng)然,也包括Python。
Python提供了一種面向?qū)ο蟮木幊田L(fēng)格,今天,我就來(lái)循序漸進(jìn)的講解一下Python面向?qū)ο?,保證哪怕是零基礎(chǔ)小白在看完這篇文章后也能夠徹底搞明白Python面向?qū)ο蟆?/p>
在本文中,我將從如下幾個(gè)主題給大家介紹Python面向?qū)ο缶幊痰幕A(chǔ)知識(shí):
類
對(duì)象
繼承
屬性
方法
1 基本概念
1.1 類
什么是OOP中的類?
首先,借助一張圖片來(lái)理解這個(gè)概念。
從上面圖片,我們可以看到如下信息:類、對(duì)象、屬性、方法和一只皮卡丘。
這與OOP有什么關(guān)系?
好吧,上面的圖片正是幫助我們理解OOP概念的東西。
所以,現(xiàn)在進(jìn)入第一個(gè)話題。
OOP中的類是什么意思?類的定義是 “類是同一類型的對(duì)象的集合“。
把這個(gè)定義與上面的例子聯(lián)系起來(lái)。
在這幅圖中,我們可以看到有一個(gè)名為 小精靈(Pokemon)的矩形框,這就是類的名稱。
因此,簡(jiǎn)而言之,類只不過(guò)是一個(gè)對(duì)象的集合。因此,在pokemon宇宙中的所有pokemon都在 “pokemon”類下。
?
為了確保理解,再講一個(gè)示例。
以我們經(jīng)常會(huì)見(jiàn)到的汽車為例,日產(chǎn)、特斯拉、福特、豐田,這些可以理解為一個(gè)個(gè)的對(duì)象,而“汽車”則是這一系列對(duì)象的合成、集合。
1.2 對(duì)象
前面已經(jīng)反復(fù)的提到對(duì)象這個(gè)概念,接下來(lái)再具體的解釋一下。
在OOP中,對(duì)象是一個(gè)類的組成部分或成員??紤]到我們的小精靈例子,每個(gè)小精靈都是小精靈類的一個(gè)對(duì)象。比如說(shuō)。皮卡丘是口袋妖怪類的一個(gè)對(duì)象。比如說(shuō),豐田就是汽車的一個(gè)對(duì)象。
1.3 屬性
回到我們的Pokemon例子,讓我們專注于圖像中的皮卡丘。觀察它一會(huì)兒。你看到了什么?
通過(guò)觀察皮卡丘的圖像,我們可以看到它有兩只耳朵,兩只手,兩條腿,臉頰上有兩個(gè)紅色的小圓點(diǎn),還有一個(gè)顯著的黃色。
在圖片中的鄰接表格中,我們還看到了一些東西,例如,名稱=”皮卡丘”,類型=”電動(dòng)”和健康狀況=70。
因此,所有這些都被稱為屬性,屬性是提供關(guān)于類或?qū)ο蟮念~外信息的元素。
在這種情況下,所有這些屬性都提供了關(guān)于皮卡丘對(duì)象的額外信息,如顏色、健康狀況等。
1.4 方法
在Pokemon示例中,在圖表中可以看到諸如attack(),?dodge(),?evolve()這些東西,這就是所謂的方法。
更簡(jiǎn)單地解釋,方法基是與某個(gè)特定對(duì)象相關(guān)的動(dòng)作。
在這種情況下,這些動(dòng)作與我們的皮卡丘對(duì)象有關(guān)。
到此為止,想必很多同學(xué)對(duì)面向?qū)ο笾械囊恍└拍钣辛嘶镜牧私狻?/p>
下面,就實(shí)踐起來(lái),看一下Python面向?qū)ο蟮降自撛趺从谩?/p>
2 實(shí)踐
2.1 創(chuàng)建類
class Pokemon():
正如你從上面的代碼中所看到的,在Python中創(chuàng)建一個(gè)類時(shí),需要遵循一定的結(jié)構(gòu)。
以關(guān)鍵字class開(kāi)頭,通過(guò)這種方式,Python可以識(shí)別出我們要?jiǎng)?chuàng)建的東西將被視為一個(gè)類。
關(guān)鍵字class之后是類的名稱,在本例中是 Pokemon。
最后,它的后面是(),然后是:字符。
當(dāng)然,到這里類還沒(méi)有創(chuàng)建好,還需要一些其他的內(nèi)容。
創(chuàng)建__init__方法
繼續(xù)我們的類的創(chuàng)建任務(wù),下一步涉及到創(chuàng)建一個(gè)非常特殊的方法,名為_(kāi)_init__。
你可能會(huì)問(wèn):這個(gè)__init__方法是什么?
為了簡(jiǎn)單理解這個(gè)概念,可以認(rèn)為init方法類似于Java中的構(gòu)造方法。
我之前專門寫過(guò)一篇文章進(jìn)行介紹,想深入了解的可以看一下:
先給出具體代碼:
class Pokemon():
def __init__():
從上面代碼可以看到,已經(jīng)在Python中創(chuàng)建了__init__方法。
在這里,我們注意到一件事,那就是名為def的關(guān)鍵字,在Python中主要用于創(chuàng)建函數(shù)或者方法使用。
添加屬性
目前已經(jīng)定義了__init__( )方法,但是,它仍然沒(méi)有被完全定義。仍然需要在__init__( )方法中傳遞某些參數(shù)來(lái)完成它的定義。
接下來(lái),讓給__init__( )方法中添加這些參數(shù)。
class Pokemon():
def __init__(self,name,Type,health):
self.name = name
self.Type = Type
self.health = health
從上面代碼可以看到,我在__init__( )方法中傳遞了很多參數(shù)?,F(xiàn)在讓我們回過(guò)頭來(lái)了解一下這里傳遞的是什么參數(shù)。
還記得前面介紹的概念吧?我們討論過(guò)皮卡丘是黃色的,臉頰上有兩個(gè)紅點(diǎn),等等。這些是與一個(gè)對(duì)象相關(guān)的屬性,在這個(gè)__init__ ( )方法中,我們定義這些屬性。
除此之外,再解釋一下另外一個(gè)問(wèn)題:self的用途是什么?
簡(jiǎn)單地解釋一下,self是一個(gè)關(guān)鍵字,負(fù)責(zé)將這些屬性連接到我們的類,也就是本例中的Pokemon。
2.2 創(chuàng)建方法
到此為止,我們已經(jīng)聲明了我們的類,名為_(kāi)_init__()的特殊方法和類的屬性。
接下來(lái),繼續(xù)進(jìn)行最后的部分,即方法的創(chuàng)建。
class Pokemon():
def __init__(self,name,Type,health):
self.name = name
self.Type = Type
self.health = health
def attack(self):
print(“Electric attack!”)
def dodge(self):
print(“Pikachu Dodge!”)
def evolve(self):
print(“Evolving to Raichu!”)
正如你可以從上面的代碼中看到的,我創(chuàng)建3個(gè)名為attack()、dodge()、evolve()的方法。
觀察這段代碼,你可以看到我們?yōu)槊總€(gè)方法都傳遞了一個(gè)名為self的參數(shù)。在這里,正在使用self關(guān)鍵字將這個(gè)方法與我們的類連接起來(lái)。
到此為止,就創(chuàng)建了一個(gè)完整的類。
2.3 創(chuàng)建對(duì)象
首先,給出創(chuàng)建對(duì)象的代碼,在這里我創(chuàng)建了一個(gè)名為pk1的對(duì)象:
pk1 = Pokemon(“Pikachu”,”Electric”,120)
創(chuàng)建完對(duì)象之后,我們就可以做很多操作。
訪問(wèn)屬性
我們可以通過(guò)<對(duì)象名>.<屬性>的方法來(lái)訪問(wèn)對(duì)象的屬性,來(lái)看一下具體的代碼:
pk1.name # 輸出:Pikachu
pk1.Type # 輸出:Electric
pk1.health # 輸出:120
訪問(wèn)方法
訪問(wèn)方法和訪問(wèn)屬性類型<對(duì)象名>.<方法>,同樣,用具體代碼來(lái)更加清晰的解釋一下:
pk1.attack() # 輸出:Electric attack!
pk1.dodge() # 輸出:Pikachu Dodge!
pk1.evolve() # 輸出:Evolving to Raichu!
到這里,就講解完了Python面向?qū)ο缶幊痰幕緝?nèi)容。
下面,就再進(jìn)階一下,介紹一下面向?qū)ο缶幊讨械?strong>繼承。
2.4 繼承
繼承是OOP中的關(guān)鍵概念之一,同樣,借助一個(gè)簡(jiǎn)單的例子來(lái)更加輕松理解這個(gè)概念。
?
考慮一個(gè)超級(jí)跑車的例子,邁凱輪 720S spyder,這是一輛超級(jí)跑車。
正如你所看到的,像大多數(shù)其他汽車一樣,它有一些共同的特征,如門,擋風(fēng)玻璃,4個(gè)輪子,頭燈,尾燈,等等。
然而,由于它是一輛超級(jí)跑車,它有自己的定制特征,如720馬力的V8渦輪增壓發(fā)動(dòng)機(jī),由邁凱輪開(kāi)發(fā)的定制變速箱,以及定制的AWD(全輪驅(qū)動(dòng))系統(tǒng)。
現(xiàn)在將其與面向?qū)ο蟮男g(shù)語(yǔ)聯(lián)系起來(lái),我們可以說(shuō)這輛車是從它的父類中繼承了某種特征,在這種情況下,它首先是一個(gè)汽車類。
這就是 “繼承”背后的概念。
繼承是一種現(xiàn)象,一個(gè)元素從它的父類中獲得特征。在這種情況下,邁凱輪720S spyder繼承了汽車類的所有共同特征,但與此同時(shí),它本身也有某些特殊的特征。
超類和子類
我們的元素所繼承的類(本例中的汽車類)被稱為超類(Superclass),它具有通用性。
而繼承這些特征的類被稱為子類(Subclass),它在本質(zhì)上是特殊的。
接下來(lái),在 Python 中實(shí)現(xiàn)這些概念。
在這個(gè)例子中,我將創(chuàng)建兩個(gè)類–一個(gè)是名為Car的類,它就是超類。另一個(gè)是名為McLaren的類,它是子類。這個(gè)McLaren類將繼承Car類的所有屬性。
class Car():
def __init__(self,ndoors,nwheels,tailLight,headLight):
self.ndoors = ndoors
self.nwheels = nwheels
self.tailLight = tailLight
self.headLight = headLight
在這里,已經(jīng)創(chuàng)建了第一個(gè)名為Car的類。
現(xiàn)在,我們將創(chuàng)建一個(gè)名為McLaren的新類,它將繼承這個(gè)類的所有屬性。
class McLaren(Car):
def __init__(self,ndoors,nWheels,tailLight,headLight,Engine,Wheel_Drive):
Car.__init__(self,ndoors,nWheels,tailLight,headLight)
self.Engine = Engine
self.Wheel_Drive = Wheel_Drive
def Drive(self):
print(“I am driving McLaren 720S Spyder”)
正如你在上面的代碼中看到的,由于McLaren類繼承了Car類,我們?cè)趧?chuàng)建McLaren類時(shí)把Car作為參數(shù)之一,這是Python類繼承一種機(jī)制。
下面,我們創(chuàng)建一個(gè)McLaren的對(duì)象,驗(yàn)證一下它是否繼承了Car特征。
mk1 = McLaren(“4″,”4″,”Yes”,”Yes”,”V8″,”AWD”)
然后,再訪問(wèn)一下對(duì)象的屬性:
mk1.Engine # 輸出:V8
mk1.Wheel_Drive # 輸出:AWD
在這里我們可以看到,我們能夠訪問(wèn)McLaren對(duì)象中專門定義的特殊屬性,這些屬性在基類Car中是沒(méi)有的。
在這里我們繼承了我們的基類,讓我們看看基類中的那些屬性是否在我們的McLaren類中被繼承了。
mk1.headLight # 輸出:YES
mk1.ndoors # 輸出:4
mk1.nWheels # 輸出:4
可以看到,新創(chuàng)建的McLaren類的對(duì)象繼承了Car基類的所有特征,表明在這個(gè)上下文中,繼承被正確地實(shí)現(xiàn)了。
到此為止,從基本概念到實(shí)踐,涵蓋 Python中類、對(duì)象、特殊方法、屬性、方法等概念和具體實(shí)現(xiàn),已經(jīng)全面的介紹了Python面相對(duì)象中的相關(guān)知識(shí)和內(nèi)容,是不是已經(jīng)徹底了解Python面相對(duì)象了?