python 物件導向的程式設計

來源:互聯網
上載者:User

標籤:物件導向設計   基礎   電腦   訊息   col   img   wrapper   注意   沒有   

一:什麼是編程範式?

  編程是程式員用特定的文法 + 資料結構 + 演算法組成的代碼來告訴電腦如何執行任務的過程。

  如果把編程的過程比喻為練習武功,那麼編程範式指的就是武林中的各種流派,而在編程的世界裡最常見的兩大流派便是:面向過程與物件導向。

  “功夫的流派沒有高低之分,只有習武的人才有高低之分“,在編程世界裡更是這樣,面向過程與物件導向在不同的情境下都各有優劣,誰好誰壞不能一概而論。

  一個程式是程式員為了得到一個任務結果而編寫的一組指令的集合,正所謂條條大路通羅馬,實現一個任務的方式有很多種不同的方法,對這些不同的編程方式的特點進行歸納總結得出來的編程方式類別,即為編程範式,不同的編程範式本質上代表對各種各類的任務採取的不同的解決問題的思路,大多數語言只支援一種編程範式,當然也有一些語言可以同時支援多種編程範式。兩種最重要的編程範式分別是面向過程編程和物件導向編程。

 

二:什麼是面向過程編程?

   面向過程編程依賴 -  procedures,一個procedure包含一組要被進行計算的步驟, 面向過程又被稱為top-down languages, 就是程式從上到下一步步執行,一步步從上到下,從頭到尾的解決問題 。基本設計思路就是程式一開始是要著手解決一個大的問題,然後把一個大問題分解成很多個小問題或子過程,這些子過程再執行的過程再繼續分解直到小問題足夠簡單到可以在一個小步驟範圍內解決。

  舉個典型的面向過程的例子, 寫一個資料遠程備份程式, 分三步,本機資料打包,上傳至雲端服務器,測試備份檔案可用性。

def cloud_upload(file):        print("\nconnecting cloud storage center...")        print("cloud storage connected.")        print("upload file...xxx..to cloud...", file)        print(‘close connection.....‘)def data_backup(folder):    print("找到要備份的目錄...", folder)    print("將備份檔案打包,移至相應目錄...")    return ‘/tmp/backup20181103.zip‘def data_backup_test():    print("\n從另外一台機器將備份檔案從遠程cloud center下載,看檔案是否無損")def main():    zip_file = data_backup("c:\\users\\alex\歐美100G高清無碼")    cloud_upload(zip_file)    data_backup_test()if __name__ == ‘__main__‘:    main()

  這個變數,那這個子過程你也要修改,假如又有一個其它子程式依賴這個子過程 , 那就會發生一連串的影響,隨著程式越來越大, 這種編程方式的維護難度會越來越高。

test = 1def cloud_upload(file):    if test == 1:        print("\nconnecting cloud storage center...")        print("cloud storage connected.")        print("upload file...xxx..to cloud...", file)        print(‘close connection.....‘)        return True    else:        print("不備份")        return Falsedef data_backup(folder):    print("找到要備份的目錄...", folder)    print("將備份檔案打包,移至相應目錄...")    return ‘/tmp/backup20181103.zip‘def data_backup_test(upload_res):    if upload_res == 1:        print("\n從另外一台機器將備份檔案從遠程cloud center下載,看檔案是否無損")    else:        print("upload error,不備份")def main():    zip_file = data_backup("c:\\users\\alex\歐美100G高清無碼")    res = cloud_upload(zip_file)    data_backup_test(res)if __name__ == ‘__main__‘:    main()

  所以我們一般認為, 如果你只是寫一些簡單的指令碼,去做一些一次性任務,用面向過程的方式是極好的,但如果你要處理的任務是複雜的,且需要不斷迭代和維護 的, 那還是用物件導向最方便了。

 三:物件導向編程的引子

  你現在是一家遊戲公司的開發人員,現在需要你開發一款叫做<人狗大戰>的遊戲,你就思考呀,人狗作戰,那至少需要2個角色,一個是人, 一個是狗,且人和狗都有不同的技能,比如人拿棍打狗, 狗可以咬人,怎麼描述這種不同的角色和他們的功能呢?

  你搜羅了自己掌握的所有技能,寫出了下面的代碼來描述這兩個角色

person = {    ‘name‘:‘Alex‘,    ‘attack‘: 100, #殺傷力    ‘life_value‘:1000}dog = {    ‘name‘:‘Peiqi‘,    ‘attack‘: 200, #殺傷力    ‘life_value‘:800}

  一個字典表示一個角色實體,但是如果有多條狗和多個人一起打呢?那就得寫多個字典

person = {    ‘name‘:‘Alex‘,    ‘attack‘: 100, #殺傷力    ‘life_value‘:1000}person2 = {    ‘name‘:‘Black Girl‘,    ‘attack‘: 100, #殺傷力    ‘life_value‘:600}dog = {    ‘name‘:‘Peiqi‘,    ‘attack‘: 200, #殺傷力    ‘life_value‘:800}

  這樣是有問題的,因為如果你字典裡的值不小心定義錯了,把attack寫成了了atteck的話,那整個程式就有問題了。so 你很快想出了改進方案,把字典放進函數

def person(name,attack,life_value):    data = {        ‘name‘:name,        ‘attack‘:attack,        ‘life_value‘:life_value,    }    return datadef dog(name, attack, life_value):    data = {        ‘name‘: name,        ‘attack‘: attack,        ‘life_value‘: life_value,    }    return dataalex = person("Alex",100,1000)rain = person("Black girl",80,700)d = dog("PeiQi",200,800)

  好,現在角色定義好了,還差每個角色的功能,人打狗,狗咬人的功能要定義出來

def attack(p,d):    """人打狗功能"""    d[‘life_value‘] -= p[‘attack‘] #被打了,要掉血    print("人[%s] 打了 狗[%s]。。。,[%s]的生命值還有[%s]" % (p[‘name‘], d[‘name‘],d[‘name‘],d[‘life_value‘]))def bite(d,p):    """狗咬人功能"""    p[‘life_value‘] -= d[‘attack‘]    print("狗[%s] 咬了 人[%s]。。。,[%s]的生命值還有[%s]" % (d[‘name‘], p[‘name‘],p[‘name‘],p[‘life_value‘]))alex = person("Alex",100,1000)black_girl = person("Black girl",80,700)d = dog("PeiQi",200,800)attack(alex,d)bite(d,black_girl)

  但是要設定許多許多的功能,我們是不是要一點點的加?那麼久特別麻煩,改這個改那個的,為瞭解決上面的問題,我們使用物件導向。

四:什麼是物件導向?

  OOP(Object Oriented Programing)編程是利用“類”和“對象”來建立各種模型來實現對真實世界的描述。

  怎麼說呢?

  核心是“對象”二字,要理解對象為何物,必須把自己當成上帝,在上帝眼裡,世間存在的萬物皆為對象,不存在的也可以創造出來。程式員基於物件導向設計程式就好比如來設計西遊記,如來要解決的問題是把經書傳給東土大唐,如來並沒有考慮問題的解決流程,而是設計出了負責取經的師傅四人:唐僧,沙和尚,豬八戒,孫悟空,負責騷擾的一群妖魔鬼怪,以及負責保駕護航的一眾神仙,這些全都是對象,然後取經開始,就是師徒四人與妖魔鬼怪神仙互動著直到完成取經任務。所以說基於物件導向設計程式就好比在創造一個世界,世界是由一個個對象組成,而你就是這個世界的上帝。

  我們從西遊記中的任何一個人物對象都不難總結出:對象是特徵與技能的結合體。比如孫悟空的特徵是:毛臉雷公嘴,技能是:七十二變、火眼金睛等。

  與面向過程機械式的思維方式形成鮮明對比,物件導向更加註重對現實世界而非流程的類比,是一種“上帝式”的思維方式。

面向過程 == 個人視角
我要去做大保健,我只需考慮,我有沒有錢,去哪家店,怎麼去,做什麼價位的就可以,你的每一步都要通過程式定義出來,寫死了,在這個程式裡,你只被設定了去做大保健的功能,你說中途我想去個ktv,那可能會導致整個程式的邏輯都得更改。 用面向過程的方式寫代碼,那你care的就是整個事情的執行過程
物件導向 == 上帝視角
如果你是上帝,你現在要創世紀,把這麼多人、動物、山河造出來,上帝光靠自己幹,一個一個的造人,多累呀,讓你幹這個活,你肯定是先造模子,一個男人模子,一個女人模子,剩下的就一個個複製就行啦。這個模子的作用是什嗎?模子定義了人這個物種所具備的所有特徵\(或者說,我們把具備這些特徵的個體歸為人類\)。這個世界上所有的東西都是你定義的,你需要用最高效的方式去造世界,最高效的方式就是,先把世界按物種、樣貌、有無生命等各種維度分類,然後給每類東西建模型,再讓其在不脫離你基本橫型定義的架構下,自我繁衍(世界要多姿多彩,所以即使是同一物種,也要有些不一樣)

  

五:物件導向和面向過程的優缺點對比面向過程

  優點

  • 複雜的問題流程化,進而簡單化(一個複雜的問題,分成一個個小的步驟去實現,實現小的步驟將會非常簡單)
  • 舉個典型的面向過程的例子, 寫一個資料遠程備份程式, 分三步,本機資料打包,上傳至雲端服務器,測試備份檔案可用性。

  缺點

  • 一套流水線或者流程就是用來解決一個問題,比如生產汽水的流水線無法生產汽車,即便是能,也得是大改,改一個組件,與其相關的組件都需要修改,牽一髮而動全身,擴充性極差。
  • 比如我們修改了步驟二的函數cloud_upload的邏輯,那麼依賴於步驟二結果才能正常執行的步驟三的函數data_backup_test相關的邏輯也需要修改,這就造成了連鎖反應,而這一弊端會隨著程式的增大而變得越發的糟糕,我們程式的維護難度將會越來越大。

  應用情境

  面向過程的程式設計思想一般用於那些功能一旦實現之後就很少需要改變的情境, 如果你只是寫一些簡單的指令碼,去做一些一次性任務,用面向過程的方式是極好的,著名的例子有Linux內核,git,以及Apache HTTP Server等。但如果你要處理的任務是複雜的,且需要不斷迭代和維護 的, 那還是用物件導向最方便了。

物件導向

  優點:

  解決了面向過程可擴充性低的問題,需要強調的是,對於一個軟體品質來說,物件導向的程式設計並不代表全部,物件導向的程式設計只是用來解決擴充性問題。

 

  缺點:

  編程的複雜度遠高於面向過程,不瞭解物件導向而立即上手並基於它設計程式,極容易出現過度設計的問題,而且在一些擴充性要求低的情境使用物件導向會徒增編程難度,比如管理linux系統的shell指令碼程式就不適合用物件導向去設計,面向過程反而更加適合。

  應用情境:

  當然是應用於需求經常變化的軟體中,一般需求的變化都集中在使用者層,互連網應用,企業內部軟體,遊戲等都是物件導向的程式設計大顯身手的好地方。

六:為什麼要用物件導向?
  1. 使程式更加容易擴充和易更改,使開發效率變的更高
  2. 基於物件導向的程式可以使它人更加容易理解你的代碼邏輯,從而使團隊開發變得更從容。
七:物件導向名詞解釋

  類:一個類即是對一類擁有相同屬性的對象的抽象、藍圖、原型、模板。在類中定義了這些對象的都具備的屬性(variables(data))、共同的方法

  屬性:人類包含很多特徵,把這些特徵用程式來描述的話,叫做屬性,比如年齡、身高、性別、姓名等都叫做屬性,一個類中,可以有多個屬性

  方法:人類不止有身高、年齡、性別這些屬性,還能做好多事情,比如說話、走路、吃飯等,相比較於屬性是名詞,說話、走路是動詞,這些動詞用程式來描述就叫做方法。

  執行個體(對象):一個對象即是一個類的執行個體化後執行個體,一個類必須經過執行個體化後方可在程式中調用,一個類可以執行個體化多個對象,每個對象亦可以有不同的屬性,就像人類是指所有人,每個人是指具體的對象,人與人之前有共性,亦有不同

  執行個體化:把一個類轉變為一個對象的過程就叫執行個體化

 

八:物件導向三大特性

1,Encapsulation 封裝

  在類中對資料的賦值、內部調用對外部使用者是透明的,這使類變成了一個膠囊或容器,裡麵包含著類的資料和方法

2,Inheritance 繼承

  一個類可以派生出子類,在這個父類裡定義的屬性、方法自動被子類繼承

3,Polymorphism 多態

  多態是物件導向的重要特性,簡單點說:“一個介面,多種實現”,指一個基類中派生出了不同的子類,且每個子類在繼承了同樣的方法名的同時又對父類的方法做了不同的實現,這就是同一種事物表現出的多種形態。

 

  編程其實就是一個將具體世界進行抽象化的過程,多態就是抽象化的一種體現,把一系列具體事物的共同點抽象出來, 再通過這個抽象的事物, 與不同的具體事物進行對話。

  對不同類的對象發出相同的訊息將會有不同的行為。比如,你的老闆讓所有員工在九點鐘開始工作, 他只要在九點鐘的時候說:“開始工作”即可,而不需要對銷售人員說:“開始銷售工作”,對技術人員說:“開始技術工作”, 因為“員工”是一個抽象的事物, 只要是員工就可以開始工作,他知道這一點就行了。至於每個員工,當然會各司其職,做各自的工作。

  多態允許將子類的對象當作父類的對象使用,某父類型的引用指向其子類型的對象,調用的方法是該子類型的方法。這裡引用和調用方法的代碼編譯前就已經決定了,而引用所指向的對象可以在運行期間動態綁定

 

 九:Python中關於OPP的常用術語

9.1 抽象/實現

  抽象指對現實世界問題和實體的本質表現,行為和特徵建模,建立一個相關的子集,可以用於 繪程式結構,從而實現這種模型。抽象不僅包括這種模型的資料屬性,還定義了這些資料的介面。

  對某種抽象的實現就是對此資料及與之相關介面的現實化(realization)。現實化這個過程對於客戶 程式應當是透明而且無關的。 

9.2 封裝/介面

  封裝描述了對資料/資訊進行隱藏的觀念,它對資料屬性提供介面和訪問函數。通過任何用戶端直接對資料的訪問,無視介面,與封裝性都是背道而馳的,除非程式員允許這些操作。作為實現的 一部分,用戶端根本就不需要知道在封裝之後,資料屬性是如何組織的。在Python中,所有的類屬性都是公開的,但名字可能被“混淆”了,以阻止未經授權的訪問,但僅此而已,再沒有其他預防措施了。這就需要在設計時,對資料提供相應的介面,以免客戶程式通過不規範的操作來存取封裝的資料屬性。

  注意:封裝絕不是等於“把不想讓別人看到、以後可能修改的東西用private隱藏起來”

真正的封裝是,經過深入的思考,做出良好的抽象,給出“完整且最小”的介面,並使得內部細節可以對外透明

(注意:對外透明的意思是外部調用者可以順利的得到自己想要的任何功能,完全意識不到內部細節的存在)

9.3 合成

  合成擴充了對類的 述,使得多個不同的類合成為一個大的類,來解決現實問題。合成 述了 一個異常複雜的系統,比如一個類由其它類組成,更小的組件也可能是其它的類,資料屬性及行為, 所有這些合在一起,彼此是“有一個”的關係。

9.4 派生/繼承/繼承結構

  派生描述了子類衍生出新的特性,新類保留已存類類型中所有需要的資料和行為,但允許修改或者其它的自訂動作,都不會修改原類的定義。
繼承描述了子類屬性從祖先類繼承這樣一種方式
  繼承結構表示多“代”派生,可以述成一個“族譜”,連續的子類,與祖先類都有關係。

9.5 泛化/特化

基於繼承
  泛化表示所有子類與其父類及祖先類有一樣的特點。
  特化描述所有子類的自訂,也就是,什麼屬性讓它與其祖先類不同。

9.6 多態與多態性

  多態指的是同一種事物的多種狀態:水這種事物有多種不同的狀態:冰,水蒸氣

  多態性的概念指出了對象如何通過他們共同的屬性和動作來操作及訪問,而不需考慮他們具體的類。

  冰,水蒸氣,都繼承於水,它們都有一個同名的方法就是變成雲,但是冰.變雲(),與水蒸氣.變雲()是截然不同的過程,雖然調用的方法都一樣

9.7 自省/反射

  自省也稱作反射,這個性質展示了某對象是如何在運行期取得自身資訊的。如果傳一個對象給你,你可以查出它有什麼能力,這是一項強大的特性。如果Python不支援某種形式的自省功能,dir和type內建函數,將很難正常工作。還有那些特殊屬性,像__dict__,__name__及__doc__

 

十:小白容易犯的錯誤

  1.物件導向的程式設計看起來高大上,所以我在編程時就應該保證通篇class,這樣寫出的程式一定是好的程式(物件導向只適合那些可擴充性要求比較高的情境)

  2.很多人喜歡說物件導向三大特性(這是從哪傳出來的,封裝,多態,繼承?漏洞太多太多,好吧暫且稱為三大特性),那麼我在基於物件導向編程時,我一定要讓我定義的類中完整的包含這三種特性,這樣寫肯定是好的程式

  好傢夥,我說降龍十八掌有十八掌,那麼你每次跟人幹仗都要從第一掌打到第18掌這才顯得你會了是麼:面對敵人,你打到第三掌對方就已經倒下了,你說,不行,你給老子起來,老子還沒有show完...

  3.類有類屬性,執行個體有執行個體屬性,所以我們在定義class時一定要定義出那麼幾個類屬性,想不到怎麼辦,那就使勁的想,定義的越多越牛逼

這就犯了一個嚴重的錯誤,程式越早物件導向,死的越早,為啥物件導向,因為我們要將資料與功能結合到一起,程式整體的結構都沒有出來,或者說需要考慮的問題你都沒有搞清楚個八九不離十,你就開始物件導向了,這就導致了,你在那裡幹想,自以為想通了,定義了一堆屬性,結果後來又都用不到,或者想不通到底應該定義啥,那就一直想吧,想著想著就瘋了。

你見過哪家公司要開發一個軟體,上來就開始寫,肯定是頻繁的開會討論計劃。

  4.既然這麼麻煩,那麼我徹底解脫了,我們不要用物件導向編程了,你啊,你有大才,你能成事啊,傻叉。

 十一:物件導向的軟體開發

  很多人在學完了python的class機制之後,遇到一個生產中的問題,還是會懵逼,這其實太正常了,因為任何程式的開發都是先設計後編程,python的class機制只不過是一種編程方式,如果你硬要拿著class去和你的問題死磕,變得更加懵逼都是分分鐘的事,在以前,軟體的開發相對簡單,從任務的分析到編寫程式,再到程式的調試,可以由一個人或一個小組去完成。但是隨著軟體規模的迅速增大,軟體任意麵臨的問題十分複雜,需要考慮的因素太多,在一個軟體中所產生的錯誤和隱藏的錯誤、未知的錯誤可能達到驚人的程度,這也不是在設計階段就完全解決的。

    所以軟體的開發其實一整套規範,我們所學的只是其中的一小部分,一個完整的開發過程,需要明確每個階段的任務,在保證一個階段正確的前提下再進行下一個階段的工作,稱之為軟體工程

    物件導向的軟體工程包括下面幾個部:

1.物件導向分析(object oriented analysis ,OOA)

    軟體工程中的系統分析階段,要求分析員和使用者結合在一起,對使用者的需求做出精確的分析和明確的表述,從大的方面解析軟體系統應該做什麼,而不是怎麼去做。物件導向的分析要按照物件導向的概念和方法,在對任務的分析中,從客觀存在的事物和事物之間的關係,貴南出有關的對象(對象的‘特徵’和‘技能’)以及對象之間的聯絡,並將具有相同屬性和行為的對象用一個類class來標識。

    建立一個能反映這是工作情況的需求模型,此時的模型是粗略的。

2 物件導向設計(object oriented design,OOD)

    根據物件導向分析階段形成的需求模型,對每一部分分別進行具體的設計。

    首先是類的設計,類的設計可能包含多個層次(利用繼承與派生機制)。然後以這些類為基礎提出程式設計的思路和方法,包括對演算法的設計。

    在設計階段並不牽涉任何一門具體的電腦語言,而是用一種更通用的描述工具(如虛擬碼或流程圖)來描述

3 物件導向編程(object oriented programming,OOP)

    根據物件導向設計的結果,選擇一種電腦語言把它寫成程式,可以是python

4 物件導向測試(object oriented test,OOT)

    在寫好程式後交給使用者使用前,必須對程式進行嚴格的測試,測試的目的是發現程式中的錯誤並修正它。

    面向對的測試是用物件導向的方法進行測試,以類作為測試的基本單元。

5 物件導向維護(object oriendted soft maintenance,OOSM)

    正如對任何產品都需要進行售後服務和維護一樣,軟體在使用時也會出現一些問題,或者軟體商想改進軟體的效能,這就需要修改程式。

    由於使用了物件導向的方法開發程式,使用程式的維護比較容易。

    因為對象的封裝性,修改一個對象對其他的對象影響很小,利用物件導向的方法維護程式,大大提高了軟體維護的效率,可擴充性高。

 

    在物件導向方法中,最早發展的肯定是物件導向編程(OOP),那時OOA和OOD都還沒有發展起來,因此程式設計者為了寫出物件導向的程式,還必須深入到分析和設計領域,尤其是設計領域,那時的OOP實際上包含了現在的OOD和OOP兩個階段,這對程式設計者要求比較高,許多人感到很難掌握。

    現在設計一個大的軟體,是嚴格按照物件導向軟體工程的5個階段進行的,這個5個階段的工作不是由一個人從頭到尾完成的,而是由不同的人分別完成,這樣OOP階段的任務就比較簡單了。程式編寫者只需要根據OOd提出的思路,用物件導向語言編寫出程式既可。

 

python 物件導向的程式設計

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.