Python基礎教程08 - 物件導向的基本概念

pythontab發表於2014-05-12

Python使用類(class)和物件(object),進行物件導向(object-oriented programming,簡稱OOP)的程式設計。

物件導向的最主要目的是提高程式的重複使用性。我們這麼早切入物件導向程式設計的原因是,Python的整個概念是基於物件的。瞭解OOP是進一步學習Python的關鍵。

下面是對物件導向的一種理解,基於分類。

相近物件,歸為類

在人類認知中,會根據屬性相近把東西歸類,並且給類別命名。比如說,鳥類的共同屬性是有羽毛,透過產卵生育後代。任何一隻特別的鳥都在鳥類的原型基礎上的。

物件導向就是模擬了以上人類認知過程。在Python語言,為了聽起來酷,我們把上面說的“東西”稱為物件(object)。

先定義鳥類

class Bird(object):
    have_feather = True
    way_of_reproduction  = 'egg'

我們定義了一個類別(class),就是鳥(Bird)。在隸屬於這個類比的語句塊中,我們定義了兩個變數,一個是有羽毛(have_feather),一個是生殖方式(way_of_reproduction),這兩個變數對應我們剛才說的屬性(attribute)。我們暫時先不說明括號以及其中的內容,記為問題1。

假設我養了一隻小雞,叫summer。它是個物件,且屬於鳥類。使用前面定義的類:

summer = Bird()
print summer.way_of_reproduction

透過第一句建立物件,並說明summer是類別鳥中的一個物件,summer就有了鳥的類屬性,對屬性的引用是透過 物件.屬性(object.attribute) 的形式實現的。

可憐的summer,你就是個有毛產的蛋貨,好不精緻。

動作

日常認知中,我們在透過屬性識別類別的時候,有時根據這個東西能做什麼事情來區分類別。比如說,鳥會移動。這樣,鳥就和房屋的類別區分開了。這些動作會帶來一定的結果,比如移動導致位置的變化。

這樣的一些“行為”屬性為方法(method)。Python中透過在類的內部定義函式,來說明方法。

class Bird(object):
    have_feather = True
    way_of_reproduction = 'egg'
    def move(self, dx, dy):
        position = [0,0]
        position[0] = position[0] + dx
        position[1] = position[1] + dy
        return position
summer = Bird()
print 'after move:',summer.move(5,8)

我們重新定義了鳥這個類別。鳥新增一個方法屬性,就是表示移動的方法move。(我承認這個方法很傻,你可以在看過下一講之後定義個有趣些的方法)

(它的引數中有一個self,它是為了方便我們引用物件自身。方法的第一個引數必須是self,無論是否用到。有關self的內容會在下一講展開)

另外兩個引數,dx, dy表示在x、y兩個方向移動的距離。move方法會最終返回運算過的position。

在最後呼叫move方法的時候,我們只傳遞了dx和dy兩個引數,不需要傳遞self引數(因為self只是為了內部使用)。

我的summer可以跑了。

子類

類別本身還可以進一步細分成子類

比如說,鳥類可以進一步分成雞,大雁,黃鸝。

在OOP中,我們透過繼承(inheritance)來表達上述概念。

class Chicken(Bird):
    way_of_move = 'walk'
    possible_in_KFC = True
class Oriole(Bird):
    way_of_move = 'fly'
    possible_in_KFC = False
summer = Chicken()
print summer.have_feather
print summer.move(5,8)

新定義的雞(Chicken)類的,增加了兩個屬性:移動方式(way_of_move),可能在KFC找到(possible_in_KFC)

在類定義時,括號裡為了Bird。這說明,Chicken是屬於鳥類(Bird)的一個子類,即Chicken繼承自Bird。自然而然,Bird就是Chicken的父類。Chicken將享有Bird的所有屬性。儘管我只宣告瞭summer是雞類,它透過繼承享有了父類的屬性(無論是變數屬性have_feather還是方法屬性move)

新定義的黃鸝(Oriole)類,同樣繼承自鳥類。在建立一個黃鸝物件時,該物件自動擁有鳥類的屬性。

透過繼承製度,我們可以減少程式中的重複資訊和重複語句。如果我們分別定義兩個類,而不繼承自鳥類,就必須把鳥類的屬性分別輸入到雞類和黃鸝類的定義中。整個過程會變得繁瑣,因此,物件導向提高了程式的可重複使用性。

(回到問題1, 括號中的object,當括號中為object時,說明這個類沒有父類(到頭了))

將各種各樣的東西分類,從而瞭解世界,從人類祖先開始,我們就在練習了這個認知過程,物件導向是符合人類思維習慣的。所謂程式導向,也就是執行完一個語句再執行下一個,更多的是機器思維。透過物件導向的程式設計,我們可以更方便的表達思維中的複雜想法。

總結

將東西根據屬性歸類 ( 將object歸為class )

方法是一種屬性,表示動作

用繼承來說明父類-子類關係。子類自動具有父類的所有屬性。

self代表了根據類定義而建立的物件。

建立對一個物件: 物件名 = 類名()

引用物件的屬性: object.attribute


相關文章