面向對象的4個基本特徵

上個週末霸筆大唐移動的應用程序軟件工程師試題,有一道面向對象的4個特徵,以前都是接觸的三個,怎麼多出了一個?原來就是抽象性。。。

面向對象的4個基本特徵
在上述面向對象的基本概念基礎之上,不可避免地要涉及到面向對象程序設計所具有的4個共同特徵:抽象性、封裝性、繼承性和多態性。
1.抽象
抽象是人們認識事物的常用方法,比如地圖的繪製。抽象的過程就是如何簡化、概括所觀察到的現實世界,併爲人們所用的過程。
抽象是軟件開發的基礎。軟件開發離不開現實環境,但需要對信息細節進行提煉、抽象,找到事物的本質和重要屬性。
抽象包括兩個方面:過程抽象和數據抽象。過程抽象把一個系統按功能劃分成若干個子系統,進行"自頂向下逐步求精"的程序設計。數據抽象以數據爲中心,把數據類型和施加在該類型對象上的操作作爲一個整體(對象)來進行描述,形成抽象數據類型ADT。
所有編程語言的最終目的都是提供一種"抽象"方法。一種較有爭議的說法是:解決問題的複雜程度直接取決於抽象的種類及質量。其中,"種類"是指準備對什麼進行"抽象"。彙編語言是對基礎機器的少量抽象。後來的許多"命令式"語言(如FORTRAN、BASIC和C)是對彙編語言的一種抽象。與彙編語言相比,這些語言已有了較大的進步,但它們的抽象原理依然要求程序設計者着重考慮計算機的結構,而非考慮問題本身的結構。在機器模型(位於"方案空間")與實際解決的問題模型(位於"問題空間")之間,程序員必須建立起一種聯繫。這個過程要求人們付出較大的精力,而且由於它脫離了編程語言本身的範圍,造成程序代碼很難編寫,而且要花較大的代價進行維護。由此造成的副作用便是一門完善的"編程方法"學科。
爲機器建模的另一個方法是爲要解決的問題製作模型。對一些早期語言來說,如LISP和APL,它們的做法是"從不同的角度觀察世界"、"所有問題都歸納爲列表"或"所有問題都歸納爲算法"。PROLOG則將所有問題都歸納爲決策鏈。對於這些語言,可以認爲它們一部分是面向基於"強制"的編程,另一部分則是專爲處理圖形符號設計的。每種方法都有自己特殊的用途,適合解決某一類的問題。但只要超出了它們力所能及的範圍,就會顯得非常笨拙。
面向對象的程序設計在此基礎上則跨出了一大步,程序員可利用一些工具來表達問題空間內的元素。由於這種表達非常普遍,所以不必受限於特定類型的問題。人們將問題空間中的元素以及它們在方案空間的表示物稱作"對象"。當然,還有一些在問題空間沒有對應體的其他對象。通過添加新的對象類型,程序可進行靈活的調整,以便與特定的問題配合。所以在閱讀方案的描述代碼時,會讀到對問題進行表達的話語。與以前的方法相比,這無疑是一種更加靈活、更加強大的語言抽象方法。
總之,OOP允許人們根據問題,而不是根據方案來描述問題。然而,仍有一個聯繫途徑回到計算機。每個對象都類似一臺小計算機;它們有自己的狀態,而且可要求它們進行特定的操作。與現實世界的"對象"或者"物體"相比,編程"對象"與它們也存在共通的地方:它們都有自己的特徵和行爲。
2.封裝
封裝是面向對象編程的特徵之一,也是類和對象的主要特徵。封裝將數據以及加在這些數據上的操作組織在一起,成爲有獨立意義的構件。外部無法直接訪問這些封裝了的數據,從而保證了這些數據的正確性。如果這些數據發生了差錯,也很容易定位錯誤是由哪個操作引起的。
如果外部需要訪問類裏面的數據,就必須通過接口(Interface)進行訪問。接口規定了可對一個特定的對象發出哪些請求。當然,必須在某個地方存在着一些代碼,以便滿足這些請求。這些代碼與那些隱藏起來的數據叫作"隱藏的實現"。站在過程化程序編寫(Procedural Programming)的角度,整個問題並不顯得複雜。一種類型含有與每種可能的請求關聯起來的函數。一旦向對象發出一個特定的請求,就會調用那個函數。通常將這個過程總結爲向對象"發送一條消息"(提出一個請求)。對象的職責就是決定如何對這條消息作出反應(執行相應的代碼)。
若任何人都能使用一個類的所有成員,那麼可對這個類做任何事情,則沒有辦法強制他們遵守任何約束--所有東西都會暴露無遺。
有兩方面的原因促使了類的編制者控制對成員的訪問。第一個原因是防止程序員接觸他們不該接觸的東西--通常是內部數據類型的設計思想。若只是爲了解決特定的問題,用戶只需操作接口即可,無需明白這些信息。類向用戶提供的實際是一種服務,因爲他們很容易就可看出哪些對自己非常重要,以及哪些可忽略不計。進行訪問控制的第二個原因是允許庫設計人員修改內部結構,不用擔心它會對客戶程序員造成什麼影響。例如,編制者最開始可能設計了一個形式簡單的類,以便簡化開發。以後又決定進行改寫,使其更快地運行。若接口與實現方法早已隔離開,並分別受到保護,就可放心做到這一點,只要求用戶重新鏈接一下即可。
封裝考慮的是內部實現,抽象考慮的是外部行爲。符合模塊化的原則,使得軟件的可維護性、擴充性大爲改觀。
3.繼承
繼承是一種聯結類的層次模型,並且允許和鼓勵類的重用,它提供了一種明確表述共性的方法。對象的一個新類可以從現有的類中派生,這個過程稱爲類的繼承。新類繼承了原始類的特性,新類稱爲原始類的派生類(子類),而原始類稱爲新類的基類(父類)。派生類可以從它的基類那裏繼承方法和實例變量,並且派生類可以修改或增加新的方法使之更適合特殊的需求。這也體現了大自然中一般與特殊的關係。繼承性很好地解決了軟件的可重用性問題。比如說,所有的Windows應用程序都有一個窗口,它們可以看作都是從一個窗口類派生出來的。但是有的應用程序用於文字處理,有的應用程序用於繪圖,這是由於派生出了不同的子類,各個子類添加了不同的特性。
關於繼承的詳細討論,將在第4.1~4.2節進行。
4.多態性
多態性是指允許不同類的對象對同一消息作出響應。比如同樣的加法,把兩個時間加在一起和把兩個整數加在一起肯定完全不同。又比如,同樣的選擇"編輯"、"粘貼"操作,在字處理程序和繪圖程序中有不同的效果。多態性包括參數化多態性和運行時多態性。多態性語言具有靈活、抽象、行爲共享、代碼共享的優勢,很好地解決了應用程序函數同名問題。
關於多態性的討論,將在4.7~4.9節進行。
最後,以Alan Kay的話作爲本節的結束語。他總結了Smalltalk(這是第一種成功的面向對象程序設計語言,也是Java的基礎語言)的五大基本特徵。通過這些特徵,讀者可以理解"純粹"的面向對象程序設計方法。
(1)所有東西都是對象。可將對象想象成一種新型變量,它保存着數據,但可要求它對自身進行操作。理論上講,可從要解決的問題上,提出所有概念性的組件,然後在程序中將其表達爲一個對象。
(2)程序是一大堆對象的組合。通過消息傳遞,各對象知道自己該做些什麼。爲了向對象發出請求,需向那個對象"發送一條消息"。更具體地講,可將消息想象爲一個調用請求,它調用的是從屬於目標對象的一個子例程或函數。
(3)每個對象都有自己的存儲空間,可容納其他對象。或者說,通過封裝現有對象,可製作出新型對象。所以,儘管對象的概念非常簡單,但在程序中卻可達到任意高的複雜程度。
(4)每個對象都有一種類型。根據語法,每個對象都是某個"類(Class)"的一個"實例"。其中,"類"是"類型(Type)"的同義詞。一個類最重要的特徵就是"能將什麼消息發給它?"。
(5)同一類所有對象都能接收相同的消息。這實際是別有含義的一種說法,讀者不久便能理解。由於類型爲"圓(Circle)"的一個對象也屬於類型爲"形狀(Shape)"的一個對象,所以一個"圓"完全能接收"形狀"的消息。這意味着可讓程序代碼統一指揮"形狀",令其自動控制所有符合"形狀"描述的對象,其中自然包括"圓"。這一特性稱爲對象的"可替換性",是OOP最重要的概念之一。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章