1、面向對象編程python
面向對象--Object Oriented Programming,簡稱oop,是一種程序設計思想。在說面向對象以前,先說一下什麼是編程範式,編程範式你按照什麼方式來去編程,去實現一個功能。舉個例子,你要作飯,能夠用電磁爐,也能夠用煤氣竈。不一樣的編程範式本質上表明對各類類型的任務採起的不一樣的解決問題的思路,兩種最重要的編程範式分別是面向過程編程和麪向對象編程。編程
提到面向對象,就不得不提到另外一種編程思想,面向過程;什麼是面向過程呢,面向過程的思想是把一個項目、一件事情按照必定的順序,從頭至尾一步一步地作下去,先作什麼,後作什麼,一直到結束。這種思想比較好理解,其實這也是一我的作事的方法,咱們以前編程的思想也都是使用這種思想。這種編程思想,只要前面有一個步驟變了,那麼後面的就也要變,後面維護起來比較麻煩,這樣的編程思想,咱們在寫一些簡單的小程序、只執行一次的腳本時可使用。而面向對象呢,面向對象的思想是把一個項目、一件事情分紅更小的項目,或者說分紅一個個更小的部分,每一部分負責什麼方面的功能,最後再由這些部分組合而成爲一個總體。這種思想比較適合多人的分工合做,就像一個大的機關,分各個部門,每一個部門分別負責某樣職能,各個部門能夠充分發揮本身的特點,只要符合必定前提就好了。小程序
舉個例子:好比剛纔說的一個大的機關,要作某一個項目,從面向過程的思想來講,應該是這樣分析的,先怎麼樣,再怎麼樣,最後怎麼樣。第同樣應該如何完成,第二樣應該如何完成等等。等到每一步驟都完成,項目也就完成了。而面向對象的思想則應該是這樣想的,這個項目是由幾個部分組成的,咱們就作好分工,成立一個部門來作一個部分的功能,另外一個部門來作另外一個部分。各個部門能夠不用理解其餘部門的事,只要完成本身那一部分的事情就OK了。編程語言
2、面向對象的特性函數式編程
類:class函數
類,對比現實世界來講就是一個種類,一個模型。oop
一個類便是對一類擁有相同屬性的對象的抽象、藍圖、原型。設計
在類中定義了這些對象的都具有的屬性(variables(data))、共同的方法。對象
對象:objectblog
對象,也就是指模型造出來的具體的東西。
一個對象便是一個類的實例化後實例,一個類必須通過實例化後方可在程序中調用,一個類能夠實例化多個對象,每一個對象亦能夠有不一樣的屬性,就像人類是指全部人,每一個人是指具體的對象,人與人以前有共性,亦有不一樣。
實例化:
初始化一個類,造了一個對象。把一個類變成一個具體的對象的過程,叫作實例化。
封裝:
把一些功能的實現細節不對外暴露,類中對數據的賦值、內部調用對外部用戶是透明的,這使類變成了一個膠囊或容器,裏面包含着類的數據和方法。
好比說造的一我的,你把他身體內部的什麼心肝脾肺腎都封裝起來了,其餘人都看不到,你直接找這我的。
繼承:
一個類能夠派生出子類,在這個父類裏定義的屬性、方法自動被子類繼承。好比說你繼承了你父親的姓。
python3中多繼承都是廣度優先,python2中經典類的多繼承是深度優先,新式類的多繼承是按照廣度優先的。
繼承是爲了代碼的重用
多態:
對不一樣類的對象發出相同的消息將會有不一樣的行爲。好比,你的老闆讓全部員工在九點鐘開始工做, 他只要在九點鐘的時候說:「開始工做」便可,而不須要對銷售人員說:「開始銷售工做」,對技術人員說:「開始技術工做」, 由於「員工」是一個抽象的事物, 只要是員工就能夠開始工做,他知道這一點就好了。至於每一個員工,固然會各司其職,作各自的工做。
多態就是抽象化的一種體現,把一系列具體事物的共同點抽象出來, 再經過這個抽象的事物, 與不一樣的具體事物進行對話。
一種接口,多種實現。
3、面向對象的好處
對於編程語言的初學者來說,OOP不是一個很容易理解的編程方式,你們雖然都按老師講的都知道OOP的三大特性是繼承、封裝、多態,而且你們也都知道了如何定義類、方法等面向對象的經常使用語法,可是一到真正寫程序的時候,仍是不少人喜歡用函數式編程來寫代碼,特別是初學者,很容易陷入一個窘境就是「我知道面向對象,我也會寫類,但我依然沒發如今使用了面向對象後,對咱們的程序開發效率或其它方面帶來什麼好處,由於我使用函數編程就能夠減小重複代碼並作到程序可擴展了,爲啥子還用面向對象?」對於此,我我的以爲緣由應該仍是由於你沒有充分了解到面向對象能帶來的好處。
不管用什麼形式來編程,咱們都要明確記住如下原則:
寫重複代碼是很是很差的低級行爲
你寫的代碼須要常常變動
開發正規的程序跟那種寫個運行一次就扔了的小腳本一個很大不一樣就是,你的代碼老是須要不斷的更改,不是修改bug就是添加新功能等,因此爲了往後方便程序的修改及擴展,你寫的代碼必定要遵循易讀、易改的原則(專業數據叫可讀性好、易擴展)。
若是你把一段一樣的代碼複製、粘貼到了程序的多個地方以實如今程序的各個地方調用,這個功能,那往後你再對這個功能進行修改時,就須要把程序裏多個地方都改一遍,這種寫程序的方式是有問題的,由於若是你不當心漏掉了一個地方沒改,那可能會致使整個程序的運行都 出問題。 所以咱們知道 在開發中必定要努力避免寫重複的代碼,不然就至關於給本身再挖坑。
還好,函數的出現就能幫咱們輕鬆的解決重複代碼的問題,對於須要重複調用的功能,只須要把它寫成一個函數,而後在程序的各個地方直接調用這個函數名就行了,而且當須要修改這個功能時,只需改函數代碼,而後整個程序就都更新了。
其實OOP編程的主要做用也是使你的代碼修改和擴展變的更容易,那麼小白要問了,既然函數都能實現這個需求了,還要OOP幹毛線用呢? 呵呵,說這話就像,古時候,人們打仗殺人都用刀,後來出來了槍,它的主要功能跟刀同樣,也是殺人,而後小白就問,既然刀能殺人了,那還要槍幹毛線,哈哈,顯而易見,由於槍能更好更快更容易的殺人。函數編程與OOP的主要區別就是OOP可使程序更加容易擴展和易更改。
4、類
一些概念:
屬性:屬性就是類裏面的一個變量,有類變量和實例變量,類變量是類在定義的時候就有的,實例變量是在實例化的時候才產生的變量。這個能夠理解爲,人是一個類,他的名字、年齡、性別就是它的屬性。
方法:方法就是類的功能,也就是定義在類裏面的函數,它實現了某個功能,好比說人有睡覺的功能。
構造函數:什麼是構造函數,就是類在實例化的時候作的某些初始化操做,好比說人,你造一個汽車的時候,它得有顏色、型號等等。
析構函數:析構函數就是這個實例在銷燬的時候作的一些操做。
定義類:
定義類使用class關鍵字,類名通常咱們開發的時候首字母要大寫。python中有經典類和新式類,他倆在python3中沒有區別,在python2中經典類在多繼承的時候是深度優先,新式類是廣度優先。python3中統一是廣度優先,這個後面在說繼承的時候會說。
class Car():#模型,模板 def __del__(self): #析構函數,這個實例被銷燬的執行的。 print('over..') def my_self(self): print( '我是一個汽車 個人顏色是【%s】,我有【%s】個窗戶'%(self.color,self.window) ) self.price = 10002 def run(self): print(self.color) print(self.window) print(self.price) print('汽車在跑。。。') def __init__(self,color,window): # #構造函數,是類在初始化的時候會執行它 #若是你的類在實例化的時候要傳入一些參數,那麼你就要在__init__這個函數裏寫參數了 self.color = color #綁定屬性 self.window = window print('執行我了。。') #把模型作成實際的一個汽車,這個過程叫作實例化。 bus = Car('黃色','3開門') #實例化 bus2 = Car('黑色','4開門') #實例化 bus3 = Car('粉色','2開門') #實例化 bus.my_self() # bus2.my_self() bus3.my_self() #實例就是指具體造出來的東西,經過類實例化處理的東西,就是實例 #對象,就是實例
繼承:
class F(object): ''' 這個是父類 ''' def __init__(self,name,sex): self.name = name self.sex = sex def info():#方法 print('name is %s sex is %s '%(self.name,self.sex)) class S(F):#繼承F這個類 pass s1 = S('牛牛','男')#實例化子類 s1.info()#由於繼承父類,因此父類的方法他都有 那若是在父類裏面有一個方法,子類裏面也有的話,可是子類想重寫一下父類的方法,增長新功能下面這麼寫: class test(): def __init__(self,name): self.name = name class test1(test): def __init__(self,name,age): # test.__init__(self,name)#修改父類的方法,這個是經典類裏面的寫法 super(test1,self).__init__(name)#和上面的效果同樣,這個是新式類裏面的寫法 self.name = name self.age = age test1('name','age') 多繼承,上面寫的都是單繼承的,python裏面還支持多繼承,多繼承就是繼承多個父類,在python3中多繼承都是廣度優先的,在python2中有點不一樣,經典類是深度優先,新式類是廣度優先。 class A: def say(self): print('A') class B(A): # pass def say(self): print('B') class C(A): pass # def say(self): # print('c') class D(C,B): pass s=D() s.say()
多態:python裏面是不直接支持多態的,能夠經過別的方法來實現多態。經過下面的例子就能夠實現一種接口,多種實現,對於下面的cry方法來講,無論你傳入的是什麼對象,只要有cry的方法,都會去調用它的cry方法,不用再一個個的去調用了
class Animal(object): ''' 父類 ''' def __init__(self,name): self.name = name class Dog(Animal): ''' 狗類,有叫的方法 ''' def cry(self): print('狗 [%s] 汪汪汪'%self.name) class Cat(Animal): ''' 貓類,有叫的方法 ''' def cry(self): print('貓 [%s] 喵喵喵'%self.name) def cry(obj): ''' 定義一個函數,去調用傳進來的實例的cry方法 ''' obj.cry() d1 = Dog('大黃')#實例化狗 d2 = Dog('小黃')#實例化狗 c1 = Cat('小白')#實例化貓 c2 = Cat('小黑')#實例化貓 cry(d1)#把對象d1傳進來 cry(d2)#把對象d2傳進來 objs = [d1,d2,c1,c2]#把上面實例化的對象都放到一個list裏面 for obj in objs:#循環統一調用 cry(obj)
私有方法,私有屬性:什麼是私有,私有就是隻有在類裏面能夠訪問,實例化以後不能夠訪問和調用,有私有方法和私有屬性。私有就把變量名或者函數名前面加上"__"兩個下劃線,其實就是經過私有來實現封裝的。
class Dog(object): __type = '狗'#私有屬性 def cry(self): self.__test()#調用私有方法 print('私有屬性%s'%self.__type) print('狗 [%s] 汪汪汪'%self.name) def __test(self):#私有方法 self.name = 'test'# d = D() d.cry()#正常能夠調用 d.__type#報錯,由於是私有屬性,在外面不能訪問 d.__test()#報錯,由於是私有方法,在外面不能訪問
靜態方法和類方法:
class Stu(object): country = 'china'#類變量 def __init__(self,name): self.name = name @staticmethod #靜態方法,和類自己沒有什麼關係了,就至關於在類裏面定義了一個方法而已 def say(): print('xxx') @classmethod#類方法 #靜態方法,和類方法不一樣的是,它可使用類變量,必需要傳一個值,表明的就是這個類 def hello(cls): print(cls.country) def hi(self): #這個是實例方法 print(self.name) t = Stu('name') Stu.hello() Stu.say() t.hi() t.say() t.hello()