【第八天】Python的類與物件.屬性

weixin_34239169發表於2018-03-20

第四章

4.1

1.面嚮物件語言(Object-Oriented-Language)的來歷

要想了解物件導向,就要先來了解類(Class)和物件(Object)
還記得程式導向中的模組和函式嗎,它們提高了程式的可複用性
類和物件同樣提高了程式的可複用性,除此之外
類和物件這兩種語法結構還加強了程式模擬真實世界的能力
“模擬”正是物件導向程式設計的核心

py也是一門物件導向語言,比java的歷史更加悠久
只不過py允許程式設計師以純粹程式導向的方式來使用它
所以人們有時會忽視它那顆物件導向的心


11103252-f13a47d31a6cd48a.jpg
沒有物件搞什麼物件導向程式設計T_T

(c語言是面向結構也就是程式導向
面向結構,是把要實現的功能分成很多模組即函式
每個模組承擔某一功能,每個模組可能會多次利用
這樣就只需呼叫函式就行,不用重新定義,節省了程式碼和時間
物件導向,是我們把要實現的功能打包封裝定義成一個類即一個物件
一個物件他既有多個屬性也有多個行為,用類作為程式設計的單元
要實現這個類的功能還得把類實現,就是用類定義物件
就像面向結構裡的函式定義後,你還得呼叫函式才能用函式的功能
類可以實現很多功能及物件的行為,也就是可以包含很多函式模組和變數
類與類直接可以通訊也就是屬性的傳遞就就是變數值的傳遞
這就比面向結構更加抽象,抽象級別更高。)

2.類

在日常生活中,我們把相似的東西歸為一類,並且給這個類起一個名字
比如說,鳥類的共同屬性事有羽毛,通過產卵生育後代
任何一隻特別的鳥類都是建立在鳥類的原型基礎上的

下面用py語言來記錄上面的想法,描述鳥類:

class Bird(object):
    feather = True
    reproduction = 'egg'

在這裡,我們用關鍵字class來定義一個類,類的名字就是鳥(Bird)
括號裡有一個關鍵詞object,也就是‘東西’的意思,即某個個體
在計算機語言中,我們把個體稱為物件,一個類別下,可以有多個個體

冒號和縮排說明了屬於這個類的程式碼,在隸屬於這個類別的程式塊中
我們定義了兩個量,一個用於說明鳥類有羽毛(feather)
另一個用於說明鳥類的繁衍方式(reproduction)
這兩個量稱為類的屬性(attribute)

我們除了用資料性的屬性來分辨類別外,有時也根據這類東西能做什麼事情區分
這樣的一些行為屬性稱為方法(method),py中
一般通過在類的內部定義函式來說明方法

class Bird(object):
    feather = True
    reproduction = 'egg'
    def chirp(self,sound):
        print(sound)

我們給鳥類新增一個方法屬性,就是表示鳥叫的方法chirp()
方法chirp()看起來很像個函式,它的第一個引數是self
是為了

在方法內部引用物件自身,(將在後面詳細解釋)

需要強調的是,無論該引數是否用到,方法的第一個引數必須是用於指代物件自身的self
剩下的引數sound是為了滿足我們的需求設計的,它代表了鳥叫的內容
方法chirp()會把sound列印出來

3.物件

我們定義了類,但和函式定義一樣,這還只是打造兵器的過程
為了使用這個利器,我們需要深入到物件的層面
通過呼叫類,我們可以創造出這個類下面的一個物件
比如說,我養了一隻小鳥,叫summer,它是一個物件,且屬於鳥類
我們使用前面已經定義好的鳥類,產生這個物件:

summer = Bird()

通過這一句建立物件,並說明summer是屬於鳥類的一個物件
現在,我們就可以使用鳥類中已經寫好的程式碼了
作為物件的summer將擁有鳥類的屬性和方法
對屬性的引用是通過物件.屬性(object.attribute)的形式實現的
比如說:

print(summer.reproduction)   #列印'egg'

用上面的方式,我們得到summer所屬類的繁衍方式

此外,我們還可以呼叫方法,讓summer執行鳥類允許的動作,比如:

summer.chirp('jijiji')

在呼叫方法時,我們只傳遞了一個引數,也就是字串'jijiji'
這正是方法與函式有所區別的地方,儘管在定義類的方法時
我們必須加上這個self引數,但self只能用在類定義的內部
所以在呼叫方法時不需要對self傳入資料,通過chirp()方法
我的summer就可以叫了

到現在為止,描述物件的資料都儲存於類的屬性中
類屬性描述了一個類的共性,比如,鳥類都有羽毛
所有屬於該類的物件會共享這些屬性,比如說
summer是一個鳥類的物件,因此summer也有羽毛
當然,我們可以通過某個物件來引用某個類屬性

對於一個類下的全部個體來說,某些屬性可能存在個體差異

因此,為了完整描述個體,除了共性的類屬性外
我們還需要說明個性的物件屬性,在類中,我們可以通過self來操作物件的屬性
現在我們擴充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引數設定了物件的屬性color
和類屬性一樣,我們只能通過物件.屬性的方式來操作物件屬性
由於物件屬性依賴於self,我們必須在某個方法內部才能操作類屬性
因此,物件屬性沒辦法像類屬性一樣,在類下方直接賦初值

但py還是提供了初始化物件屬性的方法
py定義了一系列特殊方法,特殊方法又被稱為魔法方法(Magic Method)
特殊方法的方法名很特別,前後有兩個下劃線,比如init()
add(),dict()等,程式設計師可以在類定義中設定特殊方法
py會以特定的方式來處理各個特殊方法,對於類的init()
py會在每次建立物件時自動呼叫,因此,我們可以在init()
方法內部來初始化物件屬性:

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()方法說明了這個類的初始化方式
每當物件建立時,比如建立summer物件時,init()方法就會被呼叫
它會設定這個物件的屬性,在後面的chirp()方法中,就可以通過self呼叫這一物件屬性
除了設定物件屬性外,我們還可以在init()中加入其他指令
這些指令會在建立物件時執行,在呼叫類時,類後面可以跟一個引數列表
這裡放入的資料將傳給init()的引數,通過init()方法
我們可以在建立物件時就初始化物件屬性

除了操作物件屬性外,self引數還有另一個功能
就是能讓我們在一個方法內部呼叫同一類的其他方法,比如:

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呼叫了類中的另一個方法chirp()

備註:

因markdown格式問題,以上正文中加粗的init(),add(),dict()
均為__init__(),__add__(),__dict__()

相關文章