python Day6 面向对象学习
面向過程 VS 面向?qū)ο?/h3> 編程范式
編程是 程序 員 用特定的語(yǔ)法+數(shù)據(jù)結(jié)構(gòu)+算法組成的代碼來(lái)告訴計(jì)算機(jī)如何執(zhí)行任務(wù)的過程 , 一個(gè)程序是程序員為了得到一個(gè)任務(wù)結(jié)果而編寫的一組指令的集合,正所謂條條大路通羅馬,實(shí)現(xiàn)一個(gè)任務(wù)的方式有很多種不同的方式, 對(duì)這些不同的編程方式的特點(diǎn)進(jìn)行歸納總結(jié)得出來(lái)的編程方式類別,即為編程范式。 不同的編程范式本質(zhì)上代表對(duì)各種類型的任務(wù)采取的不同的解決問題的思路, 大多數(shù)語(yǔ)言只支持一種編程范式,當(dāng)然也有些語(yǔ)言可以同時(shí)支持多種編程范式。 兩種最重要的編程范式分別是面向過程編程和面向?qū)ο缶幊獭?/p>
面向過程編程(Procedural Programming)
Procedural programming uses a list of instructions to tell the computer what to do step-by-step.
面向過程編程依賴 - 你猜到了- procedures,一個(gè)procedure包含一組要被進(jìn)行計(jì)算的步驟, 面向過程又被稱為top-down languages, 就是程序從上到下一步步執(zhí)行,一步步從上到下,從頭到尾的解決問題 。基本設(shè)計(jì)思路就是程序一開始是要著手解決一個(gè)大的問題,然后把一個(gè)大問題分解成很多個(gè)小問題或子過程,這些子過程再執(zhí)行的過程再繼續(xù)分解直到小問題足夠簡(jiǎn)單到可以在一個(gè)小步驟范圍內(nèi)解決。
這樣做的問題也是顯而易見的,就是如果你要對(duì)程序進(jìn)行修改,對(duì)你修改的那部分有依賴的各個(gè)部分你都也要跟著修改, 舉個(gè)例子,如果程序開頭你設(shè)置了一個(gè)變量值 為1 , 但如果其它子過程依賴這個(gè)值 為1的變量才能正常運(yùn)行,那如果你改了這個(gè)變量,那這個(gè)子過程你也要修改,假如又有一個(gè)其它子程序依賴這個(gè)子過程 , 那就會(huì)發(fā)生一連串的影響,隨著程序越來(lái)越大, 這種編程方式的維護(hù)難度會(huì)越來(lái)越高。
所以我們一般認(rèn)為, 如果你只是寫一些簡(jiǎn)單的腳本,去做一些一次性任務(wù),用面向過程的方式是極好的,但如果你要處理的任務(wù)是復(fù)雜的,且需要不斷迭代和維護(hù) 的, 那還是用面向?qū)ο笞罘奖懔恕?
面向?qū)ο缶幊?/h4>
OOP編程是利用“類”和“對(duì)象”來(lái)創(chuàng)建各種模型來(lái)實(shí)現(xiàn)對(duì)真實(shí)世界的描述,使用面向?qū)ο缶幊痰脑蛞环矫媸且驗(yàn)樗梢允钩绦虻木S護(hù)和擴(kuò)展變得更簡(jiǎn)單,并且可以大大提高程序開發(fā)效率 ,另外,基于面向?qū)ο蟮某绦蚩梢允顾烁尤菀桌斫饽愕拇a邏輯,從而使團(tuán)隊(duì)開發(fā)變得更從容。
面向?qū)ο蟮膸讉€(gè)核心特性如下
Class 類
一個(gè)類即是對(duì)一類擁有相同屬性的對(duì)象的抽象、藍(lán)圖、原型。在類中定義了這些對(duì)象的都具備的屬性(variables(data))、共同的方法
Object 對(duì)象
一個(gè)對(duì)象即是一個(gè)類的實(shí)例化后實(shí)例,一個(gè)類必須經(jīng)過實(shí)例化后方可在程序中調(diào)用,一個(gè)類可以實(shí)例化多個(gè)對(duì)象,每個(gè)對(duì)象亦可以有不同的屬性,就像人類是指所有人,每個(gè)人是指具體的對(duì)象,人與人之前有共性,亦有不同
Encapsulation 封裝
在類中對(duì)數(shù)據(jù)的賦值、內(nèi)部調(diào)用對(duì)外部用戶是透明的,這使類變成了一個(gè)膠囊或容器,里面包含著類的數(shù)據(jù)和方法
Inheritance 繼承
一個(gè)類可以派生出子類,在這個(gè)父類里定義的屬性、方法自動(dòng)被子類繼承
Polymorphism 多態(tài)
態(tài)是面向?qū)ο蟮闹匾匦?簡(jiǎn)單點(diǎn)說(shuō):“一個(gè)接口,多種實(shí)現(xiàn)”,指一個(gè)基類中派生出了不同的子類,且每個(gè)子類在繼承了同樣的方法名的同時(shí)又對(duì)父類的方法做了不同的實(shí)現(xiàn),這就是同一種事物表現(xiàn)出的多種形態(tài)。
編程其實(shí)就是一個(gè)將具體世界進(jìn)行抽象化的過程,多態(tài)就是抽象化的一種體現(xiàn),把一系列具體事物的共同點(diǎn)抽象出來(lái), 再通過這個(gè)抽象的事物, 與不同的具體事物進(jìn)行對(duì)話。
對(duì)不同類的對(duì)象發(fā)出相同的消息將會(huì)有不同的行為。比如,你的老板讓所有員工在九點(diǎn)鐘開始工作, 他只要在九點(diǎn)鐘的時(shí)候說(shuō):“開始工作”即可,而不需要對(duì)銷售人員說(shuō):“開始銷售工作”,對(duì)技術(shù)人員說(shuō):“開始技術(shù)工作”, 因?yàn)椤皢T工”是一個(gè)抽象的事物, 只要是員工就可以開始工作,他知道這一點(diǎn)就行了。至于每個(gè)員工,當(dāng)然會(huì)各司其職,做各自的工作。
多態(tài)允許將子類的對(duì)象當(dāng)作父類的對(duì)象使用,某父類型的引用指向其子類型的對(duì)象,調(diào)用的方法是該子類型的方法。這里引用和調(diào)用方法的代碼編譯前就已經(jīng)決定了,而引用所指向的對(duì)象可以在運(yùn)行期間動(dòng)態(tài)綁定。
面向?qū)ο缶幊?Object-Oriented Programming?)介紹
對(duì)于編程語(yǔ)言的初學(xué)者來(lái)講,OOP不是一個(gè)很容易理解的編程方式,大家雖然都按老師講的都知道OOP的三大特性是繼承、封裝、多態(tài),并且大家也都知道了如何定義類、方法等面向?qū)ο蟮某S谜Z(yǔ)法,但是一到真正寫程序的時(shí)候,還是很多人喜歡用函數(shù)式編程來(lái)寫代碼,特別是初學(xué)者,很容易陷入一個(gè)窘境就是“我知道面向?qū)ο?#xff0c;我也會(huì)寫類,但我依然沒發(fā)現(xiàn)在使用了面向?qū)ο蠛?#xff0c;對(duì)我們的程序開發(fā)效率或其它方面帶來(lái)什么好處,因?yàn)槲沂褂煤瘮?shù)編程就可以減少重復(fù)代碼并做到程序可擴(kuò)展了,為啥子還用面向?qū)ο?#xff1f;”。 對(duì)于此,我個(gè)人覺得原因應(yīng)該還是因?yàn)槟銢]有充分了解到面向?qū)ο竽軒?lái)的好處,今天我就寫一篇關(guān)于面向?qū)ο蟮娜腴T文章,希望能幫大家更好的理解和使用面向?qū)ο缶幊獭?? 無(wú)論用什么形式來(lái)編程,我們都要明確記住以下原則:我們看到,上面的創(chuàng)建角色時(shí),我們并沒有給__init__傳值,程序也沒未報(bào)錯(cuò),是因?yàn)?#xff0c;類在調(diào)用它自己的__init__(…)時(shí)自己幫你給self參數(shù)賦值了,
r1 = Role('Ben','police','AK47’) #此時(shí)self 相當(dāng)于 r1 , Role(r1,'Ben','police','AK47’) r2 = Role('Jack','terrorist','B22’)#此時(shí)self 相當(dāng)于 r2, Role(r2,'Jack','terrorist','B22’) 為什么這樣子?你拉著我說(shuō)你有些猶豫,怎么會(huì)這樣子? 你執(zhí)行r1?=?Role('Ben','police','AK47')時(shí),python的解釋器其實(shí)干了兩件事:?
執(zhí)行結(jié)果 #Ben has just bought B21? 依然沒給self傳值 ,但Python還是會(huì)自動(dòng)的幫你把r1 賦值給self這個(gè)參數(shù), 為什么呢? 因?yàn)?#xff0c;你在buy_gun(..)方法中可能要訪問r1的一些其它屬性呀, 比如這里就訪問 了r1的名字,怎么訪問呢?你得告訴這個(gè)方法呀,于是就把r1傳給了這個(gè)self參數(shù),然后在buy_gun里調(diào)用 self.name 就相當(dāng)于調(diào)用r1.name 啦,如果還想知道r1的生命值 有多少,直接寫成self.life_value就可以了。 說(shuō)白了就是在調(diào)用類中的一個(gè)方法時(shí),你得告訴人家你是誰(shuí)。 好啦, 總結(jié)一下2點(diǎn):面向?qū)ο蟮奶匦?#xff1a;
封裝
封裝最好理解了。封裝是面向?qū)ο蟮奶卣髦?#xff0c;是對(duì)象和類概念的主要特性。
封裝,也就是把客觀事物封裝成抽象的類,并且類可以把自己的數(shù)據(jù)和方法只讓可信的類或者對(duì)象操作,對(duì)不可信的進(jìn)行信息隱藏。
繼承
面向?qū)ο缶幊?(OOP) 語(yǔ)言的一個(gè)主要功能就是“繼承”。繼承是指這樣一種能力:它可以使用現(xiàn)有類的所有功能,并在無(wú)需重新編寫原來(lái)的類的情況下對(duì)這些功能進(jìn)行擴(kuò)展。
通過繼承創(chuàng)建的新類稱為“子類”或“派生類”。
被繼承的類稱為“基類”、“父類”或“超類”。
繼承的過程,就是從一般到特殊的過程。
要實(shí)現(xiàn)繼承,可以通過“繼承”(Inheritance)和“組合”(Composition)來(lái)實(shí)現(xiàn)。
在某些 OOP 語(yǔ)言中,一個(gè)子類可以繼承多個(gè)基類。但是一般情況下,一個(gè)子類只能有一個(gè)基類,要實(shí)現(xiàn)多重繼承,可以通過多級(jí)繼承來(lái)實(shí)現(xiàn)。
繼承概念的實(shí)現(xiàn)方式有三類:實(shí)現(xiàn)繼承、接口繼承和可視繼承。
??????????實(shí)現(xiàn)繼承是指使用基類的屬性和方法而無(wú)需額外編碼的能力; ??????????接口繼承是指僅使用屬性和方法的名稱、但是子類必須提供實(shí)現(xiàn)的能力; ??????????可視繼承是指子窗體(類)使用基窗體(類)的外觀和實(shí)現(xiàn)代碼的能力。在考慮使用繼承時(shí),有一點(diǎn)需要注意,那就是兩個(gè)類之間的關(guān)系應(yīng)該是“屬于”關(guān)系。例如,Employee 是一個(gè)人,Manager 也是一個(gè)人,因此這兩個(gè)類都可以繼承 Person 類。但是 Leg 類卻不能繼承 Person 類,因?yàn)橥炔⒉皇且粋€(gè)人。
抽象類僅定義將由子類創(chuàng)建的一般屬性和方法。OO開發(fā)范式大致為:劃分對(duì)象→抽象類→將類組織成為層次化結(jié)構(gòu)(繼承和合成) →用類與實(shí)例進(jìn)行設(shè)計(jì)和實(shí)現(xiàn)幾個(gè)階段。
繼承示例 #!_*_coding:utf-8_*_ class SchoolMember(object): members = 0 #初始學(xué)校人數(shù)為0 def __init__(self,name,age): self.name = name self.age = age def tell(self): passdef enroll(self): '''注冊(cè)'''SchoolMember.members +=1print("\033[32;1mnew member [%s] is enrolled,now there are [%s] members.\033[0m " %(self.name,SchoolMember.members)) def __del__(self): '''析構(gòu)方法'''print("\033[31;1mmember [%s] is dead!\033[0m" %self.name) class Teacher(SchoolMember): def __init__(self,name,age,course,salary): super(Teacher,self).__init__(name,age) self.course = course self.salary = salary self.enroll() def teaching(self): '''講課方法'''print("Teacher [%s] is teaching [%s] for class [%s]" %(self.name,self.course,'s12')) def tell(self): '''自我介紹方法'''msg = '''Hi, my name is [%s], works for [%s] as a [%s] teacher !''' %(self.name,'Oldboy', self.course) print(msg) class Student(SchoolMember): def __init__(self, name,age,grade,sid): super(Student,self).__init__(name,age) self.grade = grade self.sid = sid self.enroll() def tell(self): '''自我介紹方法'''msg = '''Hi, my name is [%s], I'm studying [%s] in [%s]!''' %(self.name, self.grade,'Oldboy') print(msg) if __name__ == '__main__': t1 = Teacher("Ben",22,'Python',20000) t2 = Teacher("Jack",29,'Linux',3000) s1 = Student("helln", 24,"Python S12",1483) s2 = Student("Sam", 26,"Python S12",1484) t1.teaching() t2.teaching() t1.tell() View Code多態(tài)
多態(tài)性(polymorphisn)是允許你將父對(duì)象設(shè)置成為和一個(gè)或更多的他的子對(duì)象相等的技術(shù),賦值之后,父對(duì)象就可以根據(jù)當(dāng)前賦值給它的子對(duì)象的特性以不同的方式運(yùn)作。簡(jiǎn)單的說(shuō),就是一句話:允許將子類類型的指針賦值給父類類型的指針。 那么,多態(tài)的作用是什么呢?我們知道,封裝可以隱藏實(shí)現(xiàn)細(xì)節(jié),使得代碼模塊化;繼承可以擴(kuò)展已存在的代碼模塊(類);它們的目的都是為了——代碼重用。而多態(tài)則是為了實(shí)現(xiàn)另一個(gè)目的——接口重用!多態(tài)的作用,就是為了類在繼承和派生的時(shí)候,保證使用“家譜”中任一類的實(shí)例的某一屬性時(shí)的正確調(diào)用。 ? Pyhon不直接支持多態(tài),但可以間接實(shí)現(xiàn) 通過Python模擬的多態(tài) class Animal: def __init__(self, name): # Constructor of the class self.name = name def talk(self): # Abstract method, defined by convention only raise NotImplementedError("Subclass must implement abstract method") class Cat(Animal): def talk(self): return 'Meow!'class Dog(Animal): def talk(self): return 'Woof! Woof!'animals = [Cat('Missy'), Dog('Lassie')] for animal in animals: print animal.name + ': ' + animal.talk()?
?
?
?
?
轉(zhuǎn)載于:https://www.cnblogs.com/jock911/p/5831169.html
總結(jié)
以上是生活随笔為你收集整理的python Day6 面向对象学习的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 我们不谈算法
- 下一篇: Python:Python学习总结