第八篇:面向對象編程
OOP介紹
一、什麽是OOP
1、編程的發展已經從簡單控制流中按步的指令序列進入到更有組織的方式中
2、結構化的或過程性編程可以讓我們把程序組織成邏輯塊,以便重復或重用
3、面向對象編增強了結構化編程,實現了數據與動作的融合
4、數據層和邏輯層由一個可用以創建這些對象的簡單抽象層來描述
二、常用術語
1、抽象/實現:抽象指對現實世界問題和實體的本質表現,行為和特征建模,建立一個相關的子集,可以用於描繪程序結構,從而實現這種模型
2、封裝/接口:封裝描述了對數據/信息進行隱藏的觀念,它對數據屬性提供接口和訪問函數;客戶端根本就不
需要知道在封裝之後,數據屬性是如何組織的,這就需要在設計時,對數據提供相應的接口
3、合成:合成擴充了對類的描述,使得多個不同的類合成為一個大的類,來解決現實問題
4、派生/繼承:派生描述了子類的創建,新類保留已存類類型中所有需要的數據和行為,但允許修改或者其它的自定義操作,都不會修改原類的定義
5、多態:指出了對象如何通過他們共同的屬性和動作來
操作及訪問,而不需考慮他們具體的類
6、泛化/特化:泛化表示所有子類與其父類及祖先類有一樣的特點;特化描述所有子類的自定義,也就是什麽屬性讓它與其祖先類不同
7、自省/反射:自省表示給予程序員某種能力來進行像“手工類型檢查”的工作,它也被稱為反射。這個性質展示了某對象是如何在運行期取得自身信息的
類
一、創建類
1、類是一種數據結構,我們可以用它來定義對象,對象把數據值和行為特性融合在一起
2、python使用class關鍵字來創建類
3、通常類名的第一個字母大寫
class ClassName(bases): ‘class documentation string‘ #‘類文檔字符串‘ class_suite #類體
二、類的數據屬性
1、數據屬性僅僅是所定義的類的變量
2、這種屬性已是靜態變量,或者是靜態數據。它們表示這些數據是與它們所屬的類對象綁定的,不依賴於任何類實例
3、靜態成員通常僅用來跟蹤與類相關的值
>>> class C(object): ... foo = 100 ... >>> print C.foo 100 >>> C.foo += 1 >>> print C.foo 101
三、特殊的類屬性
實例
一、創建實例
1、如果說類是一種數據結構定義類型,那麽實例則聲明了一個這種類型的變量
2、類被實例化得到實例,該實例的類型就是這個被實例化的類
3、創建實例與調用函數類似,調用一個類就創建了它的一個實例
>>> class C(object): ... foo = 100 >>> c = C() >>> print c <__main__.C object at 0x7f4f012c1ad0>
二、實例屬性
1、實例僅擁有數據屬性,數據屬性只是與某個類的實例相關聯的數據值,並且可通過句點屬性標識法來訪問
2、設置實例的屬性可以在實例創建後任意時間進行,也可以在能夠訪問實例的代碼中進行
>>> class C(object): ... pass ... >>> c = C() >>> c.hi = ‘hello‘ >>> print c.hi hello
三、特殊的實例屬性
>>> class C(object): ... pass >>> c = C() >>> c.hi = ‘hello‘ >>> c.__dict__ {‘hi‘: ‘hello‘} >>> print c.__class__ <class ‘__main__.C‘>
四、類與實例屬性對比
1、類屬性僅是與類相關的數據值,類屬性和實例無關
2、靜態成員(類的數據屬性)不會因為實例而改變它們的值,除非實例中顯式改變它
3、類和實例都是名字空間,各不相同
>>> class C(object): ... version = 1.0 >>> c = C() >>> C.version += 0.1 >>> print ‘in C version=%s, in c version=%s‘ % (C.version, c.version) in C version=1.1, in c version=1.1 >>> c.version += 0.1 >>> print ‘in C version=%s, in c version=%s‘ % (C.version, c.version) in C version=1.1, in c version=1.2
組合和派生
方法
一、__init__方法
1、__init__()是實例創建後第一個被調用的方法
2、設置實例的屬性可以在實例創建後任意時間進行,但是通常情況下優先在__init__方法中實現
#!/usr/bin/env python class AddrBook(object): def __init__(self, nm, ph): self.name = nm self.phone = ph >>> import AddrBook >>> bob = AddrBook.AddrBook(‘bob green‘, ‘13322334455‘)
二、綁定方法
1、方法僅僅是類內部定義的函數,方法只有在其所屬的類擁有實例時,才能被調用
2、任何一個方法定義中的第一個參數都是變量self,它表示調用此方法的實例對象
#!/usr/bin/env python class AddrBook(object): def getPhone(self): return self.phone >>> AddrBook.AddrBook.getPhone() #不能直接調用類的方法 Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: unbound method getPhone() must be called with AddrBook instance as first argument (got nothing instead)
三、非綁定方法
1、調用非綁定方法並不經常用到
2、需要調用一個沒有實例的類中的方法的一個主要場景是你在派生一個子類,而且要覆蓋父類的方法
#!/usr/bin/env python class AddrBook(object): def __init__(self, nm, ph): self.name = nm self.phone = ph def getPhone(self): return self.phone class EmplAddrBook(AddrBook): def __init__(self, nm, ph, id, em): AddrBook.__init__(self, nm, ph) self.emid = id self.email = em
組合
一、什麽是組合
1、類被定義後,目標就是要把它當成一個模塊來使用,並把這些對象嵌入到你的代碼中去
2、組合就是讓不同的類混合並加入到其它類中來增加功能和代碼重用性
3、可以在一個大點的類中創建其它類的實例,實現一些其它屬性和方法來增強對原來的類對象
二、實現組合
1、創建復合對象、應用組合可以實現附加的功能
2、例如,通過組合實現上述地址薄功能的增強
#!/usr/bin/env python class Info(object): def __init__(self, ph, em, qq): self.phone = ph self.email = em self.qq = qq
def updatePhone(self, newph): self.phone = newph
class Contact(object): def __init__(self, name, ph, em, qq): self.name = name self.info = Info(ph, em, qq)
子類和派生
一、創建子類
1、當類之間有顯著的不同,並且較小的類是較大的類所需要的組件時組合表現得很好;但當設計“相同的類
但有一些不同的功能”時,派生就是一個更加合理的選擇了
2、OOP 的更強大方面之一是能夠使用一個已經定義好的類,擴展它或者對其進行修改,而不會影響系統中使用現存類的其它代碼片段
3、OOD(面向對象設計)允許類特征在子孫類或子類中進行繼承
4、創建子類只需要在圓括號中寫明從哪個父類繼承即可
>>> class A(object): ... def printStar(self): ... print ‘*‘ * 20 ... >>> class B(A): ... pass
...
二、繼承
1、繼承描述了基類的屬性如何“遺傳”給派生類
2、子類可以繼承它的基類的任何屬性,不管是數據屬性還是方法
>>> class A(object): ... def printStar(self): ... print ‘*‘ * 20 ... >>> class B(A): ... pass #類B並沒有定義任何方法 ... >>> b = B() #b是B的實例 >>> b.printStar() #B繼承了類A的方法,實例b也就具備了該功能
*******************
三、通過繼承覆蓋方法
1、如果子類中有和父類同名的方法,父類方法將被覆蓋
2、如果需要訪問父類的方法,則要調用一個未綁定的父類方法,明確給出子類的實例
>>> class P(object): ... def foo(self): ... print ‘in P-foo‘ >>> class C(P): ... def foo(self): ... print ‘in C-foo‘ >>> c = C() >>> c.foo() in C-foo >>> P.foo(c) in P-foo
四、多重繼承
1、python允許多重繼承,即一個類可以是多個父類的子類,子類可以擁有所有父類的屬性
>>> class A(object): ... def foo(self): ... print ‘foo method‘ >>> class B(object): ... def bar(self): ... print ‘bar method‘ >>> class C(A, B): ... pass >>> c = C() >>> c.foo() foo method >>> c.bar() bar method
五、類和實例的內建函數
六、私有化
1、python為類元素(屬性和方法)的私有性提供初步的形式,由雙下劃線開始的屬性在運行時被“混淆”,所以直接訪問是不允許的
>>> class C(object): ... def __init__(self, nm): ... self.__name = nm ... def getName(self): ... return self.__name >>> c = C(‘bob‘) >>> c.getName() ‘bob‘ >>> c.__name #私有化的數據不能在外部直接使用 Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: ‘C‘ object has no attribute ‘__name‘
第八篇:面向對象編程