第四章
4.1
1.面向?qū)ο笳Z言(Object-Oriented-Language)的來歷
要想了解面向?qū)ο螅鸵葋砹私忸?Class)和對象(Object)
還記得面向過程中的模塊和函數(shù)嗎杆麸,它們提高了程序的可復用性
類和對象同樣提高了程序的可復用性,除此之外
類和對象這兩種語法結(jié)構(gòu)還加強了程序模擬真實世界的能力
“模擬”正是面向?qū)ο缶幊痰暮诵?/p>
py也是一門面向?qū)ο笳Z言顺又,比java的歷史更加悠久
只不過py允許程序員以純粹面向過程的方式來使用它
所以人們有時會忽視它那顆面向?qū)ο蟮男?/p>
(c語言是面向結(jié)構(gòu)也就是面向過程
面向結(jié)構(gòu),是把要實現(xiàn)的功能分成很多模塊即函數(shù)
每個模塊承擔某一功能等孵,每個模塊可能會多次利用
這樣就只需調(diào)用函數(shù)就行稚照,不用重新定義,節(jié)省了代碼和時間
面向?qū)ο蟾┟龋俏覀儼岩獙崿F(xiàn)的功能打包封裝定義成一個類即一個對象
一個對象他既有多個屬性也有多個行為果录,用類作為程序設(shè)計的單元
要實現(xiàn)這個類的功能還得把類實現(xiàn),就是用類定義對象
就像面向結(jié)構(gòu)里的函數(shù)定義后绳瘟,你還得調(diào)用函數(shù)才能用函數(shù)的功能
類可以實現(xiàn)很多功能及對象的行為雕憔,也就是可以包含很多函數(shù)模塊和變量
類與類直接可以通信也就是屬性的傳遞就就是變量值的傳遞
這就比面向結(jié)構(gòu)更加抽象,抽象級別更高糖声。)
2.類
在日常生活中,我們把相似的東西歸為一類分瘦,并且給這個類起一個名字
比如說蘸泻,鳥類的共同屬性事有羽毛,通過產(chǎn)卵生育后代
任何一只特別的鳥類都是建立在鳥類的原型基礎(chǔ)上的
下面用py語言來記錄上面的想法嘲玫,描述鳥類:
class Bird(object):
feather = True
reproduction = 'egg'
在這里悦施,我們用關(guān)鍵字class來定義一個類,類的名字就是鳥(Bird)
括號里有一個關(guān)鍵詞object去团,也就是‘東西’的意思抡诞,即某個個體
在計算機語言中穷蛹,我們把個體稱為對象,一個類別下昼汗,可以有多個個體
冒號和縮進說明了屬于這個類的代碼肴熏,在隸屬于這個類別的程序塊中
我們定義了兩個量,一個用于說明鳥類有羽毛(feather)
另一個用于說明鳥類的繁衍方式(reproduction)
這兩個量稱為類的屬性(attribute)
我們除了用數(shù)據(jù)性的屬性來分辨類別外顷窒,有時也根據(jù)這類東西能做什么事情區(qū)分
這樣的一些行為屬性稱為方法(method)蛙吏,py中
一般通過在類的內(nèi)部定義函數(shù)來說明方法
class Bird(object):
feather = True
reproduction = 'egg'
def chirp(self,sound):
print(sound)
我們給鳥類新增一個方法屬性,就是表示鳥叫的方法chirp()
方法chirp()看起來很像個函數(shù)鞋吉,它的第一個參數(shù)是self
是為了
在方法內(nèi)部引用對象自身鸦做,(將在后面詳細解釋)
需要強調(diào)的是,無論該參數(shù)是否用到谓着,方法的第一個參數(shù)必須是用于指代對象自身的self
剩下的參數(shù)sound是為了滿足我們的需求設(shè)計的泼诱,它代表了鳥叫的內(nèi)容
方法chirp()會把sound打印出來
3.對象
我們定義了類,但和函數(shù)定義一樣赊锚,這還只是打造兵器的過程
為了使用這個利器治筒,我們需要深入到對象的層面
通過調(diào)用類,我們可以創(chuàng)造出這個類下面的一個對象
比如說改抡,我養(yǎng)了一只小鳥矢炼,叫summer,它是一個對象阿纤,且屬于鳥類
我們使用前面已經(jīng)定義好的鳥類句灌,產(chǎn)生這個對象:
summer = Bird()
通過這一句創(chuàng)建對象,并說明summer是屬于鳥類的一個對象
現(xiàn)在欠拾,我們就可以使用鳥類中已經(jīng)寫好的代碼了
作為對象的summer將擁有鳥類的屬性和方法
對屬性的引用是通過對象.屬性(object.attribute)的形式實現(xiàn)的
比如說:
print(summer.reproduction) #打印'egg'
用上面的方式胰锌,我們得到summer所屬類的繁衍方式
此外,我們還可以調(diào)用方法藐窄,讓summer執(zhí)行鳥類允許的動作资昧,比如:
summer.chirp('jijiji')
在調(diào)用方法時,我們只傳遞了一個參數(shù)荆忍,也就是字符串'jijiji'
這正是方法與函數(shù)有所區(qū)別的地方格带,盡管在定義類的方法時
我們必須加上這個self參數(shù),但self只能用在類定義的內(nèi)部
所以在調(diào)用方法時不需要對self傳入數(shù)據(jù)刹枉,通過chirp()方法
我的summer就可以叫了
到現(xiàn)在為止叽唱,描述對象的數(shù)據(jù)都儲存于類的屬性中
類屬性描述了一個類的共性,比如微宝,鳥類都有羽毛
所有屬于該類的對象會共享這些屬性棺亭,比如說
summer是一個鳥類的對象,因此summer也有羽毛
當然蟋软,我們可以通過某個對象來引用某個類屬性
對于一個類下的全部個體來說镶摘,某些屬性可能存在個體差異
因此嗽桩,為了完整描述個體,除了共性的類屬性外
我們還需要說明個性的對象屬性凄敢,在類中碌冶,我們可以通過self來操作對象的屬性
現(xiàn)在我們拓展Bird類:
class Bird(object):
def chirp(self,sound):
print(sound)
def set_color(self,color):
self.color = color
summer = Bird()
summer.set_color('yellow')
print(summer.color) #打印yellow
在方法set_color()中,我們通過self參數(shù)設(shè)定了對象的屬性color
和類屬性一樣贡未,我們只能通過對象.屬性的方式來操作對象屬性
由于對象屬性依賴于self种樱,我們必須在某個方法內(nèi)部才能操作類屬性
因此,對象屬性沒辦法像類屬性一樣俊卤,在類下方直接賦初值
但py還是提供了初始化對象屬性的方法
py定義了一系列特殊方法嫩挤,特殊方法又被稱為魔法方法(Magic Method)
特殊方法的方法名很特別,前后有兩個下劃線消恍,比如init()
add(),dict()等岂昭,程序員可以在類定義中設(shè)定特殊方法
py會以特定的方式來處理各個特殊方法,對于類的init()
py會在每次創(chuàng)建對象時自動調(diào)用狠怨,因此约啊,我們可以在init()
方法內(nèi)部來初始化對象屬性:
class Bird(object):
def __init__(self,sound):
self.sound = sound
print('my sound is:',sound)
def chirp(self):
print(self.sound)
summer = Bird('ji')
summer.chirp()
my sound is: ji
ji
在上面的類定義中,我們通過 init()方法說明了這個類的初始化方式
每當對象建立時佣赖,比如創(chuàng)建summer對象時恰矩,init()方法就會被調(diào)用
它會設(shè)定這個對象的屬性,在后面的chirp()方法中憎蛤,就可以通過self調(diào)用這一對象屬性
除了設(shè)定對象屬性外外傅,我們還可以在init()中加入其他指令
這些指令會在創(chuàng)建對象時執(zhí)行,在調(diào)用類時俩檬,類后面可以跟一個參數(shù)列表
這里放入的數(shù)據(jù)將傳給init()的參數(shù)萎胰,通過init()方法
我們可以在創(chuàng)建對象時就初始化對象屬性
除了操作對象屬性外,self參數(shù)還有另一個功能
就是能讓我們在一個方法內(nèi)部調(diào)用同一類的其他方法棚辽,比如:
class Bird(object):
def chirp(self,sound):
print(sound)
def chirp_repeat(self,sound,n):
for i in range(n):
self.chirp(sound)
summer = Bird()
summer.chirp_repeat('ji',10) #重復打印'ji'10次
ji
ji
ji
ji
ji
ji
ji
ji
ji
ji
在方法chirp_repeat()中技竟,我們通過self調(diào)用了類中的另一個方法chirp()
備注:
因markdown格式問題,以上正文中加粗的init(),add(),dict()
均為__init__(),__add__(),__dict__()