- C++面向對象程序設計
- 杜茂康等編著
- 3054字
- 2019-01-01 05:54:50
1.2 面向對象程序語言的特征
概括而言,程序的組織方式大致有兩種:以功能為中心或以數據為中心。面向過程程序設計以功能為中心組織程序,而面向對象程序設計(Object-Oriented Programming,OOP)則圍繞數據進行程序組織,以數據為中心,圍繞數據設計程序代碼,由用戶定義數據及可實施于數據的操作。面向對象設計語言具有抽象、封裝、繼承和多態等基本特征。
面向對象程序設計語言經歷了一個較長的演變過程,20世紀50年代的LISP語言就引入了信息隱藏和封裝機制,60年代的Simula語言,提出了抽象和封裝,引入了數據抽象和類的概念,被認為是第一個面向對象語言(但它不具備面向對象語言的全部特征);70年代的Smalltalk則是第一個真正面向對象的程序設計語言。現在廣泛使用的C++、Eiffel、Object-C、Visual Basic、PowerBuilder、Delphi、C#、Java等都是面向對象的程序設計語言。
1.類與對象
在現實生活中,對象是指客觀存在的事物,如一個人、一條狗、一棵樹、一臺計算機等都是對象。同類對象具有相同的屬性(特征)和行為,比如所有的人都有姓名、性別、眼、手腳、身高、體重等屬性,有走路、講話、打手勢、學習和工作等行為;樓房有位置、樓層、房間數量、造價等屬性;狗有皮毛、尾巴、四條腿等屬性,有跑、吠、搖尾巴等行為;飛機能夠飛行,輪船能夠航行;如此等等。
人們借助于對象的屬性和行為認識客觀世界,將具有相同屬性和行為的客觀對象歸入同一類。利用這種分類方法,人們將客觀世界分成了人類、狗類、豬類、樹類、草類等。
每類事物都有許多實際存在的個體,這些個體則稱為對象(Object)。同類事物的不同個體,盡管有著相同的一組屬性和行為,但在屬性取值和行為表現上存在個體差異。比如,張三和李四都具有人類所共有的屬性和行為,但他們在走路、講話、打手勢、學習和工作等行為的實施方面有各自的特點,這是行為上的個體差別;他們具有不同的名字(姓名屬性不同),張三1.7米高,李四1.5米高(身高屬性不同),這些是屬性取值的差異。在現實中,人們借助于對象的屬性和行為認識和區分不同事物。
面向對象程序設計用計算機中的軟件對象模擬現實中的實際對象。它用類(class)來表示同類對象的共有屬性和行為,即用類這一概念來表示客觀世界中的同類事物。類是用歸類方法從一個個具體對象中抽取出共同特征而形成的概念。比如,張三、李四、王二……都是學生,都有學號、姓名、班級、性別等屬性,具有做作業、聽課等行為。將所有同學都共有的這些屬性和行為抽象出來,就構成了學生類。而具有一個類所指定的屬性和行為的某個個體則稱為該類的一個對象。圖1-3表示了一個學生類和其中一個對象的關系。

圖1-3 類與對象的關系
2.抽象與封裝
抽象(abstract)是指有意忽略問題的某些細節和與當前目標無關的方面,以便把問題的本質表達得更清楚。抽象在現實生活中隨處可見,如畫一幅中國地圖,如果不分主次把所有的山川、河流、城市、交通線路全畫上去,最后的結果將是一團糟。只能通過抽象,畫出中國各大省份的概況,如主要大城市、主要山脈、重要的交通線路、主要的大江大河等,有意不畫出各省中不重要的縣及小城鎮,不畫出各城市中的各條街道、公路等。道理很簡單,這樣更能反映出中國地理的整體面貌,讓人們更加清楚地了解中國地理的分布情況。
面向對象程序設計通過數據抽象來描繪客觀事物,把事物的主要特征抽取出來,有意地隱藏事物某些方面的細節,把注意力集中在事物的本質特征上面,更能把握問題的本質。數據抽象的結果將產生對應的抽象數據類型(Abstract Data Type,ADT)。
ADT把數據類型分成了接口和實現兩部分。其中,對用戶可見、用戶能夠用來完成某項任務的部分稱為接口;那些對用戶不可見、具體完成工作任務的細節則稱為實現。這如同人們常見的DVD播放機,面板上可供用戶操作使用的各種功能按鈕就是DVD的接口,各個功能按鈕(如Play)完成相應功能的細節就是實現(例如,Play如何播放DVD的具體過程,即怎樣旋轉光盤,移動激光柱,讀取光盤內容,并在電視機屏幕上顯示光盤中的圖像等過程則稱為Play接口的實現)。實現對用戶是隱藏的,用戶不知道實現的細節,也不需要知道。
數據抽象的任務是設計出清晰而足夠的接口,接口必須滿足用戶的基本需求,且允許用戶通過它訪問其底層實現。抽象的結果導致了接口與實現的分離,具體可以通過數據封裝實現。所謂封裝(encapsulation),就是將數據抽象的外部接口與內部實現細節分離開來,將接口顯示給用戶并允許其訪問,將接口的實現細節隱藏起來,不讓用戶知道,也不允許他訪問。
在面向對象程序中,封裝是通過類來實現的。類是表示客觀事物的抽象數據結構,它將數據及其操作函數包裝成一個整體,且將內部的實現細節隱藏起來,不讓類外其他對象知道,但提供了可讓外界訪問其功能的接口,通過接口與外界聯系。
例如,前面的個人通信錄管理程序,在面向對象程序設計語言(如C++)中的簡易模型如下,其中的class是用于將數據和函數組合成一個整體(即類)的語言機制。
class Person{ //用于存取個人信息的數據結構 private: char name[10]; char addr[20]; char phone[11]; public: void initData(){……} //讀入姓名、地址和電話 char* getAddr(){……}; //返回地址 char* getPhone(){……}; //返回電話號碼 };
在這個程序模型中,Person的name、addr、phone和操作數據的函數initData()、getAddr()、getPhone()被class捆綁在一起,它們是一個整體,這就是封裝。其中,private區域中的數據定義對外部程序是隱藏的,public區域中的函數是提供給外部函數訪問Person類功能的接口。程序中的任何函數只有通過public區域中的initData()、getAddr()和getPhone()等函數才能修改或查看Person的name、addr和phone數據。除此之外,再無他法。
3.繼承
繼承源于生物界,通過繼承,后代能夠獲得與其祖先相同或相似的特征與能力。面向對象程序設計語言也提供了類似于生物繼承的語言機制,允許一個新類從現有類派生而來,新類能夠繼承現有類的屬性和行為,并且能夠修改或增加新的屬性和行為,成為一個功能更強大、更能滿足應用需求的類。
繼承是面向對象程序設計語言的一個重要特征,是實現軟件復用的一個重要手段。在面向對象程序設計中,如果一個類B繼承了另外一個類A,則稱類B為子類(subclass),稱類A為超類(superclass)。

圖1-4 派生類B繼承A
C++的發明者Stroustrup認為,超類和子類這兩個概念容易讓人產生誤解,他提出了基類和派生類這兩個術語,分別用來表示超類和子類概念。本書將引用Stroustrup的術語來表示派生與繼承的關系。圖1-4是表示兩個類繼承關系的一個簡圖,表示類A是類B的基類(超類,也稱為父類),類B是類A的派生類(子類)。
派生類B繼承了基類A的所有特征和行為,盡管類B只定義了b1、b2兩個數據成員,以及f4和f5兩個成員函數。但它實際具有a1、a2、b1、b2四個數據成員,具有f1、f2、f3、f4、f5五個成員函數,其中的a1、a2、f1、f2、f3是從基類A繼承得到的。
繼承分為單繼承和多重繼承,單繼承規定每個子類只能有一個父類,圖1-4就是一個單繼承。多重繼承允許每個子類有多個父類。繼承為軟件設計提供了一種功能強大的擴展機制,允許程序員基于已經設計好的基類創建派生類,并可為派生類添加基類所不具有的屬性和行為,極大地提高了軟件復用的效率。
繼承具有以下幾個優點:
⊙ 繼承能夠清晰地體現相似類之間的層次結構關系。
⊙ 繼承能夠減少代碼和數據的重復冗余度,增強程序的重用性。
⊙ 繼承能夠通過增強一致性來減少模塊間的接口和界面,提高程序的易維護性。
⊙ 繼承是自動傳播代碼的有力工具。
⊙ 繼承是一種在普通類的基礎上構造、建立和擴展新類的最有效手段。
4.多態
多態是面向對象程序設計語言的另一重要特征,它的意思是“一個接口,多種形態”。也就是說,不同對象針對同一種操作會表現出不同的行為。多態與繼承密切相關,通過繼承產生的不同類,而這些類都分別對某個成員函數進行了定義,當這些類的對象調用該成員函數時會做出不同的響應,執行不同的操作,實現不同的功能,這就是多態。