面向對象的概述 面向對象的概念在我理解來,函數是對代碼的封裝,而類和對象是對函數的封裝,其優點如下 面向過程:根據業務邏輯從上到下寫壘代碼 函數式:將某功能代碼封裝到函數中,日後便無需重覆編寫,僅調用函數即可 面向對象:對函數進行分類和封裝,讓開發“更快更好更強... 面向對象編程是一種編程方式,此 ...
面向對象的概述
面向對象的概念在我理解來,函數是對代碼的封裝,而類和對象是對函數的封裝,其優點如下
- 面向過程:根據業務邏輯從上到下寫壘代碼
- 函數式:將某功能代碼封裝到函數中,日後便無需重覆編寫,僅調用函數即可
- 面向對象:對函數進行分類和封裝,讓開發“更快更好更強...
面向對象編程是一種編程方式,此編程方式的落地需要使用 “類” 和 “對象” 來實現,所以,面向對象編程其實就是對 “類” 和 “對象” 的使用。
類就是一個模板,模板里可以包含多個函數,函數里實現一些功能
對象則是根據模板創建的實例,通過實例對象可以執行類中的函數基本創建和使用方法如下
class為關鍵字,class為類的名稱,如果要創建一個此類的對象,只要在類名後邊加()即可
面向對象一共有三大特性,就是封裝,繼承和多態,下邊我們首先聊一下封裝。
封裝
其原理主要是利用構造方法__init__將方法或者屬性封裝到對象中去然後通過對象.方法或屬性的方式進行調用如下
class Foo: def __init__(self, name, age): self.name = name self.age = age obj1 = Foo('xiaoming', 18) print obj1.name # 直接調用obj1對象的name屬性 print obj1.age # 直接調用obj1對象的age屬性 obj2 = Foo('xiaoli', 73) print obj2.name # 直接調用obj2對象的name屬性 print obj2.age # 直接調用obj2對象的age屬性 # self 是一個形式參數,當執行 obj1 = Foo('xiaoming', 18 ) 時,self 等於 obj1 #當執行 obj2 = Foo('xiaoli', 73 ) 時,self 等於 obj2 #所以,內容其實被封裝到了對象 obj1 和 obj2 中,每個對象中都有 name 和 age 屬性,在記憶體里類似於下圖來保存。
或者通過其他的方式調用也可以,比如通過self間接調用
class Foo: def __init__(self, name, age): self.name = name self.age = age def detail(self): print self.name print self.age obj1 = Foo('wupeiqi', 18) obj1.detail() # Python預設會將obj1傳給self參數,即:obj1.detail(obj1),所以,此時方法內部的 self = obj1,即:self.name 是 wupeiqi ;self.age 是 18 obj2 = Foo('alex', 73) obj2.detail() # Python預設會將obj2傳給self參數,即:obj1.detail(obj2),所以,此時方法內部的 self = obj2,即:self.name 是 alex ; self.age 是 78
繼承
繼承就是當多個類共同擁有相同的方法時,只需要將方法提取到父類中由子類繼承,子類自然就用不用一一實現所有方法了,這點不難理解,但是python 的繼承與其他語言又不相同,python支持多繼承,就是一個子類繼承多個父類,那麼問題是,當一個方法子類沒有時,多繼承情況下是如何進行查找方法的呢
python一共兩種查找方式,如圖
- 當類是經典類時,多繼承情況下,會按照深度優先方式查找
- 當類是新式類時,多繼承情況下,會按照廣度優先方式查找
那麼,什麼是經典類和新式類呢果 當前類或者父類繼承了object類,那麼該類便是新式類,否則便是經典類。如圖
、
經典類多繼承
class D: def bar(self): print 'D.bar' class C(D): def bar(self): print 'C.bar' class B(D): def bar(self): print 'B.bar' class A(B, C): def bar(self): print 'A.bar' a = A() # 執行bar方法時 # 首先去A類中查找,如果A類中沒有,則繼續去B類中找,如果B類中麽有,則繼續去D類中找,如果D類中麽有,則繼續去C類中找,如果還是未找到,則報錯 # 所以,查找順序:A --> B --> D --> C # 在上述查找bar方法的過程中,一旦找到,則尋找過程立即中斷,便不會再繼續找了 a.bar()
新式類多繼承
class D(object): def bar(self): print 'D.bar' class C(D): def bar(self): print 'C.bar' class B(D): def bar(self): print 'B.bar' class A(B, C): def bar(self): print 'A.bar' a = A() # 執行bar方法時 # 首先去A類中查找,如果A類中沒有,則繼續去B類中找,如果B類中麽有,則繼續去C類中找,如果C類中麽有,則繼續去D類中找,如果還是未找到,則報錯 # 所以,查找順序:A --> B --> C --> D # 在上述查找bar方法的過程中,一旦找到,則尋找過程立即中斷,便不會再繼續找了 a.bar()
多態
顧名思義,多種形態, Pyhon不支持Java和C#這一類強類型語言中多態的寫法,但是原生多態,其Python崇尚“鴨子類型”。
下麵是一段偽代碼實現多態
class F1: pass class S1(F1): def show(self): print 'S1.show' class S2(F1): def show(self): print 'S2.show' # 由於在Java或C#中定義函數參數時,必須指定參數的類型 # 為了讓Func函數既可以執行S1對象的show方法,又可以執行S2對象的show方法,所以,定義了一個S1和S2類的父類 # 而實際傳入的參數是:S1對象和S2對象 def Func(F1 obj): """Func函數需要接收一個F1類型或者F1子類的類型""" print obj.show() s1_obj = S1() Func(s1_obj) # 在Func函數中傳入S1類的對象 s1_obj,執行 S1 的show方法,結果:S1.show s2_obj = S2() Func(s2_obj) # 在Func函數中傳入Ss類的對象 ss_obj,執行 Ss 的show方法,結果:S2.show