程式設計思想 物件導向

weixin_34208185發表於2018-07-31

###1.什麼是物件導向


物件導向開發方法(ObjectOriented,OO)又稱:快速原型法。

客觀世界是由各種各樣的物件組成的,每種物件都有各自的內部狀態和運動規律,不同物件之間的相互作用和聯絡就構成了各種不同的系統。 在設計和實現一個客觀系統時,在滿足需求的條件下,把系統設計成一些不可變的(相對固定)部分組成的最小集合(最好的設計)。這些不可變的部分就是所謂的物件。

###2.物件導向開發方法的組成


1、物件導向的(需求)分析OOA

2、物件導向的設計OOD

3、物件導向的程式OOP

###3.物件導向開發方法的開發過程


  1、系統調查和需求分析:對系統將要面臨的具體管理問題以及使用者對系統開發的需求進行調查研究,即先弄清要幹什麼的問題。

  2、分析問題的性質和求解問題:在繁雜的問題域中抽象地識別出物件以及其行為、結構、屬性、方法等。一般稱之為物件導向的分析,即OOA。

  3、整理問題:對分析的結果作進一步的抽象、歸類、整理,並最終以正規化的形式將它們確定下來。一般稱之為物件導向的設計,即OOD。

  4、程式實現:用物件導向的程式設計語言將上一步整理的正規化直接對映(即直接用程式設計語言來取代)為應用軟體。一般稱之為物件導向的程式,即OOP。

  5、識別客觀世界中的物件以及行為,分別獨立設計出各個物件的實體;分析物件之間的聯絡和相互所傳遞的資訊,由此構成資訊系統的模型;由資訊系統模型轉換成軟體系統的模型,對各個物件進行歸併和整理,並確定它們之間的聯絡;由軟體系統模型轉換成目標系統。

###4.物件導向的基本概念


  • 物件

物件是要研究的任何事物。從一本書到一家圖書館,單的整數到整數列龐大的資料庫、極其複雜的自動化工廠、太空梭都可看作物件,它不僅能表示有形的實體,也能表示無形的(抽象的)規則、計劃或事件。物件由資料(描述事物的屬性)和作用於資料的操作(體現事物的行為)構成一獨立整體。從程式設計者來看,物件是一個程式模組,從使用者來看,物件為他們提供所希望的行為。在對內的操作通常稱為方法。一個物件請求另一物件為其服務的方式是通過傳送訊息。

類是物件的模板。即類是對一組有相同資料和相同操作的物件的定義,一個類所包含的方法和資料描述一組物件的共同行為和屬性。類是在物件之上的抽象,物件則是類的具體化,是類的例項。類可有其子類,也可有其它類,形成類層次結構。

  • 訊息

訊息是物件之間進行通訊的一種規格說明。一般它由三部分組成:接收訊息的物件、訊息名及實際變元。

  • 繼承

繼承性(Inheritance)是指,在某種情況下,一個類會有“子類”。子類比原本的類(稱為父類)要更加具體化。例如,“狗”這個類可能會有它的子類“牧羊犬”和“吉娃娃犬”。在這種情況下,“萊絲”可能就是牧羊犬的一個例項。子類會繼承父類的屬性和行為,並且也可包含它們自己的。我們假設“狗”這個類有一個方法(行為)叫做“吠叫()”和一個屬性叫做“毛皮顏色”。它的子類(前例中的牧羊犬和吉娃娃犬)會繼承這些成員。這意味著程式設計師只需要將相同的程式碼寫一次。 在虛擬碼中我們可以這樣寫: 類牧羊犬:繼承狗定義萊絲是牧羊犬萊絲.吠叫() /* 注意這裡呼叫的是狗這個類的吠叫方法。/ 回到前面的例子,“牧羊犬”這個類可以繼承“毛皮顏色”這個屬性,並指定其為棕白色。而“吉娃娃犬”則可以繼承“吠叫()”這個方法,並指定它的音調高於平常。子類也可以加入新的成員,例如,“吉娃娃犬”這個類可以加入一個方法叫做“顫抖()”。設若用“牧羊犬”這個類定義了一個例項“萊絲”,那麼萊絲就不會顫抖,因為這個方法是屬於吉娃娃犬的,而非牧羊犬。事實上,我們可以把繼承理解為“是”或“屬於”。萊絲“是”牧羊犬,牧羊犬“屬於”狗類。因此,萊絲既得到了牧羊犬的屬性,又繼承了狗的屬性。 我們來看虛擬碼: 類吉娃娃犬:繼承狗開始 公有成員: 顫抖()結束類牧羊犬:繼承狗定義萊絲是牧羊犬萊絲.顫抖() / 錯誤:顫抖是吉娃娃犬的成員方法。 */ 當一個類從多個父類繼承時,我們稱之為“多重繼承”。如一隻狗既是吉娃娃犬又是牧羊犬(雖然事實上並不合邏輯)。多重繼承並不總是被支援的,因為它很難理解,又很難被好好使用。

  • 封裝性

具備封裝性(Encapsulation)的物件導向程式設計隱藏了某一方法的具體執行步驟,取而代之的是通過訊息傳遞機制傳送訊息給它。因此,舉例來說,“狗”這個類有“吠叫()”的方法,這一方法定義了狗具體該通過什麼方法吠叫。但是,萊絲的朋友並不知道它到底是如何吠叫的。 從例項來看: /* 一個程式導向的程式會這樣寫: /定義萊絲萊絲.設定音調(5)萊絲.吸氣()萊絲.吐氣()/ 而當狗的吠叫被封裝到類中,任何人都可以簡單地使用: */定義萊絲是狗萊絲.吠叫() 封裝是通過限制只有特定類的物件可以訪問這一特定類的成員,而它們通常利用介面實現訊息的傳入傳出。舉個例子,介面能確保幼犬這一特徵只能被賦予狗這一類。通常來說,成員會依它們的訪問許可權被分為3種:公有成員、私有成員以及保護成員。有些語言更進一步:Java可以限制同一包內不同類的訪問;C#和VB.NET保留了為類的成員聚集準備的關鍵字:internal(C#)和Friend(VB.NET);Eiffel語言則可以讓使用者指定哪個類可以訪問所有成員。[1]

  • 多型

多型(Polymorphism)是指由繼承而產生的相關的不同的類,其物件對同一訊息會做出不同的響應。例如,狗和雞都有“叫()”這一方法,但是呼叫狗的“叫()”,狗會吠叫;呼叫雞的“叫()”,雞則會啼叫。 結束定義萊絲是狗定義魯斯特是雞萊絲.叫()魯斯特.叫() 這樣,雖然同樣是做出這一種行為,但萊絲和魯斯特具體做出的表現方式將大不相同。多型性的概念可以用在運算子過載上,本文不再贅述。

  • 抽象性

抽象(Abstraction)是簡化複雜的現實問題的途徑,它可以為具體問題找到最恰當的類定義,並且可以在最恰當的繼承級別解釋問題。舉例說明,萊絲在大多數時候都被當作一條狗,但是如果想要讓它做牧羊犬做的事,你完全可以呼叫牧羊犬的方法。如果狗這個類還有動物的父類,那麼你完全可以視萊絲為一個動物。

###5.物件導向開發的特徵


  • 封裝性。物件導向方法中,程式和資料是封裝在一起的,物件作為一個實體,其操作隱藏在方法中,其狀態由物件的"屬性"來描述,並且只能通過物件中的"方法"來改變,從外界無從得知。封裝性構成了物件導向方法的基礎。因而,這種方法的創始人Codd和YOuMn認為,物件導向就是"物件+屬性+方法"。

  • 抽象性。物件導向方法中,把從具有共同性質的實體中抽象出的事物本質特徵概念,稱為"類"(Class),物件是類的一個例項。類中封裝了物件共有的屬性和方法,通過例項化一個類建立的物件,自動具有類中規定的屬性和方法。

  • 繼承性。繼承性是類特有的性質,類可以派生出子類,子類自動繼承父類的屬性與方法。這樣,在定義子類時,只須說明它不同於父類的特性,從而可大大提高軟體的可重用性。

  • 多型。所謂多型就是指一個類例項的相同方法在不同情形有不同表現形式。多型機制使具有不同內部結構的物件可以共享相同的外部介面。這意味著,雖然針對不同物件的具體操作不同,但通過一個公共的類,它們(那些操作)可以通過相同的方式予以呼叫。

###6.物件導向的五大基本原則


  • 單一職責原則SRP(Single Responsibility Principle) 是指一個類的功能要單一,不能包羅永珍。如同一個人一樣,分配的工作不能太多,否則一天到晚雖然忙忙碌碌的,但效率卻高不起來。

  • 開放封閉原則OCP(Open-Close Principle) 一個模組在擴充套件性方面應該是開放的而在更改性方面應該是封閉的。比如:一個網路模組,原來只服務端功能,而現在要加入客戶端功能, 那麼應當在不用修改服務端功能程式碼的前提下,就能夠增加客戶端功能的實現程式碼,這要求在設計之初,就應當將服務端和客戶端分開,公共部分抽象出來。

  • 替換原則(the Liskov Substitution Principle LSP) 子類應當可以替換父類並出現在父類能夠出現的任何地方。比如:公司搞年度晚會,所有員工可以參加抽獎,那麼不管是老員工還是新員工, 也不管是總部員工還是外派員工,都應當可以參加抽獎,否則這公司就不和諧了。

  • 依賴原則(the Dependency Inversion Principle DIP) 具體依賴抽象,上層依賴下層。假設B是較A低的模組,但B需要使用到A的功能, 這個時候,B不應當直接使用A中的具體類: 而應當由B定義一抽象介面,並由A來實現這個抽象介面,B只使用這個抽象介面:這樣就達到 了依賴倒置的目的,B也解除了對A的依賴,反過來是A依賴於B定義的抽象介面。通過上層模組難以避免依賴下層模組,假如B也直接依賴A的實現,那麼就可能造成迴圈依賴。一個常見的問題就是編譯A模組時需要直接包含到B模組的cpp檔案,而編譯B時同樣要直接包含到A的cpp檔案。

  • 介面分離原則(the Interface Segregation Principle ISP) 模組間要通過抽象介面隔離開,而不是通過具體的類強耦合起來

###7.為什麼需要物件導向方法


  (1)物件導向的方法更接近於人類的自然思維。人類在認識和理解現實世界中普遍運用的三個構造法則是區分物件及其屬性、區分整體物件及其組成部分、區分及形成不同物件類。而物件導向正是基於物件及屬性、類屬及成員、整體及其部分這些概念基礎之上的。因而它必然更容易被理解和運用。

  (2)系統分析、系統設計及實現之間採用同樣的角度看待問題甚至同樣的表示方法來描述間題,它們之間的連線是自然的無縫連線。

  (3)物件導向的方法將物件的屬性及服務視為一個整體。

  這更符合客觀世界的規律,從而使其理解與實現起來更加容易,進一步減少維護的費用。

  (4)繼承的方法一方面符合客觀世界的規律,一方面加強程式碼重用的可能性,以便提高軟體的開發效率。

  (5)資訊隱蔽原理使系統在變化的環境中有良好的適應性,從而使整個系統更加穩定和易於維護。

  總之,物件導向的方法一方面更易於人們理解並對映現實世界,另一方面可以提高軟體開發效率、可靠性及可維護性。

###8.程式導向和麵向物件的區別


在知乎上看到一個答案,很精闢

一個程式要完成一個任務就相當於講一個故事。 程式導向就是編年史 物件導向就是紀傳史 對於複雜的程式/巨集大的故事,事實都證明了 物件導向/紀傳是更合理的表述方法。

編年史:按照時間線索 紀傳史:按照人物線索

相關文章