面向對象的三大特性


                                                                                    繼承

什么是繼承

 

繼承是一種創建新類的方式,在python中,新建的類可以繼承一個或多個父類,父類又可稱為基類或超類,新建的類稱為派生類或子類

 

python中類的繼承分為:單繼承和多繼承

class ParentClass1: #定義父類
    pass

class ParentClass2: #定義父類
    pass

class SubClass1(ParentClass1): #單繼承,基類是ParentClass1,派生類是SubClass
    pass

class SubClass2(ParentClass1,ParentClass2): #python支持多繼承,用逗號分隔開多個繼承的類
    pass

查看繼承

>>> SubClass1.__bases__ #__base__只查看從左到右繼承的第一個子類,__bases__則是查看所有繼承的父類
(<class '__main__.ParentClass1'>,)
>>> SubClass2.__bases__
(<class '__main__.ParentClass1'>, <class '__main__.ParentClass2'>)

提示:如果沒有指定基類,python的類會默認繼承object類,object是所有python類的基類,它提供了一些常見方法(如__str__)的實現。

>>> ParentClass1.__bases__
(<class 'object'>,)
>>> ParentClass2.__bases__
(<class 'object'>,)

 

繼承與抽象(先抽象再繼承)

抽象即抽取類似或者說比較像的部分。

抽象分成兩個層次: 

1.將奧巴馬和梅西這倆對象比較像的部分抽取成類; 

2.將人,豬,狗這三個類比較像的部分抽取成父類。

抽象最主要的作用是划分類別(可以隔離關注點,降低復雜度)

 

繼承:是基於抽象的結果,通過編程語言去實現它,肯定是先經歷抽象這個過程,才能通過繼承的方式去表達出抽象的結構。

抽象只是分析和設計的過程中,一個動作或者說一種技巧,通過抽象可以得到類

 

繼承與重用性

==========================第一部分
例如

  貓可以:喵喵叫、吃、喝、拉、撒

  狗可以:汪汪叫、吃、喝、拉、撒

如果我們要分別為貓和狗創建一個類,那么就需要為 貓 和 狗 實現他們所有的功能,偽代碼如下:
 

#貓和狗有大量相同的內容
class 貓:

    def 喵喵叫(self):
        print '喵喵叫'

    def 吃(self):
        # do something

    def 喝(self):
        # do something

    def 拉(self):
        # do something

    def 撒(self):
        # do something

class 狗:

    def 汪汪叫(self):
        print '汪汪叫'

    def 吃(self):
        # do something

    def 喝(self):
        # do something

    def 拉(self):
        # do something

    def 撒(self):
        # do something



==========================第二部分
上述代碼不難看出,吃、喝、拉、撒是貓和狗都具有的功能,而我們卻分別的貓和狗的類中編寫了兩次。如果使用 繼承 的思想,如下實現:

  動物:吃、喝、拉、撒

     貓:喵喵叫(貓繼承動物的功能)

     狗:汪汪叫(狗繼承動物的功能)

偽代碼如下:
class 動物:

    def 吃(self):
        # do something

    def 喝(self):
        # do something

    def 拉(self):
        # do something

    def 撒(self):
        # do something

# 在類后面括號中寫入另外一個類名,表示當前類繼承另外一個類
class 貓(動物):

    def 喵喵叫(self):
        print '喵喵叫'
        
# 在類后面括號中寫入另外一個類名,表示當前類繼承另外一個類
class 狗(動物):

    def 汪汪叫(self):
        print '汪汪叫'
View Code

 

在開發程序的過程中,如果我們定義了一個類A,然后又想新建立另外一個類B,但是類B的大部分內容與類A的相同時

我們不可能從頭開始寫一個類B,這就用到了類的繼承的概念。

通過繼承的方式新建類B,讓B繼承A,B會‘遺傳’A的所有屬性(數據屬性和函數屬性),實現代碼重用

多態

 

封裝

面向對象的三大特性小結

面向對象的更多說明

面向對象的軟件開發

很多人在學完了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提出的思路,用面向對象語言編寫出程序既可。

    在一個大型軟件開發過程中,OOP只是很小的一個部分。

    對於全棧開發的你來說,這五個階段都有了,對於簡單的問題,不必嚴格按照這個5個階段進行,往往由程序設計者按照面向對象的方法進行程序設計,包括類的設計和程序的設計

 

幾個概念的說明

 

1.面向對象的程序設計看起來高大上,所以我在編程時就應該保證通篇class,這樣寫出的程序一定是好的程序(面向對象只適合那些可擴展性要求比較高的場景)

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

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

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

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

你見過哪家公司要開發一個軟件,上來就開始寫,肯定是頻繁的開會討論計划,請看第八節。

面向對象常用術語

抽象/實現

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

對某種抽象的實現就是對此數據及與之相關接口的現實化(realization)。現實化這個過程對於客戶 程序應當是透明而且無關的。 

封裝/接口

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

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

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

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

合成

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

派生/繼承/繼承結構

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

泛化/特化

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

多態與多態性

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

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

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

自省/反射

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM