官术网_书友最值得收藏!

1.1.3 面向對象程序設計的基本特征

面向對象程序設計方法模擬人類習慣的解題方法,代表了計算機程序設計的新的思維方法。這種方法的提出是對軟件開發方法的一場革命,是目前解決軟件開發面臨困難的最有希望、最有前途的方法之一。本節介紹面向對象程序設計的4個基本特征。

1.抽象

抽象(abstraction)是人類認識問題的最基本的手段之一。抽象是將有關事物的共性歸納、集中的過程。在抽象的過程中,通常會忽略與當前主題目標無關的那些方面,以便更充分地注意與當前目標有關的方面。抽象是對復雜世界的簡單表示,抽象并不打算了解全部信息,而只強調感興趣的信息,忽略了與主題無關的信息。例如,在設計學生成績管理系統的過程中,只關心他的姓名、學號、成績等,而對他的身高、體重等信息就可以忽略。而在學生健康信息管理系統中,身高、體重等信息必須抽象出來,而成績則可以忽略。

抽象是通過特定的實例(對象)抽取共同性質后形成概念的過程。面向對象程序設計中的抽象包括兩個方面:數據抽象和代碼抽象(或稱行為抽象)。前者描述某類對象的屬性或狀態,也就是此類對象區別于彼類對象的特征物理量;后者描述了某類對象的共同行為特征或具有的共同功能。正如前面所述的,對于一組具有相同屬性和行為的對象,可以抽象成一種類型,在C++中,這種類型為類(class),類是對象的抽象,而對象是類的實例。

抽象在系統分析、系統設計以及程序設計的發展中一直起著重要的作用。在面向對象程序設計方法中,對一個具體問題的抽象分析結果是通過類來描述和實現的。

現在以職工人事管理系統為例,通過對所有職工進行歸納、分析,抽取出其中的共性,可以得到如下的抽象描述:

(1)共同的屬性:姓名、職工號、部門等,它們組成了職工類的數據抽象部分。用C++的數據成員來表示,可以是:

(2)共同的行為:數據錄入、數據修改和數據輸出等,這構成了職工類的代碼抽象(行為抽象)部分。用C++的成員函數表示,可以是:

如果開發一個學生成績管理系統,所關心的特征就有所不同了。可見,即使對同一個研究對象,由于所研究問題的側重點不同,也可能產生不同的抽象結果。

2.封裝

封裝(encapsulation)是面向對象程序設計方法的一個重要特性。在現實世界中,所謂封裝就是把某個事物包圍起來,使外界不知道該事物的具體內容。在面向對象程序設計中,封裝是指把數據和實現操作的代碼集中起來放在對象內部,并盡可能隱蔽對象的內部細節。對象好像是一個不透明的黑盒子,表示對象屬性的數據和實現各個操作的代碼都被封裝在黑盒子里,從外面是看不見的,更不能從外面直接訪問或修改這些數據及代碼。使用一個對象時,只需知道它向外界提供的接口形式而無須知道它的數據結構細節和實現操作的算法。

C++對象中的函數名就是對象的對外接口,外界可以通過函數名來調用這些函數來實現某些行為(功能)。這些將在以后進行詳細介紹。

所謂封裝具有兩方面的含義:一是將有關的數據和操作代碼封裝在一個對象中,各個對象相對獨立、互不干擾;二是將對象中某些數據與操作代碼對外隱蔽,即隱蔽其內部細節,只留下少量接口,以便與外界聯系,接收外界的消息。這種對外界隱蔽的做法稱為信息隱蔽。信息隱蔽有利于數據安全,可以防止無關人員訪問和修改數據。

封裝的好處是可以將對象的使用者與設計者分開,大大降低了人們操作對象的復雜程度。使用者不必知道對象行為實現的細節,只需要使用設計者提供的接口即可自如地操作對象。封裝的結果實際上隱藏了復雜性,并提供了代碼重用性,從而減輕了開發一個軟件系統的難度。

3.繼承

繼承(inheritance)是面向對象程序設計的重要特性。繼承在現實生活中是一個很容易理解的概念。例如,我們每一個人都從父母身上繼承了一些特性,如種族、血型、眼睛的顏色等,我們身上的特性來自父母,也可以說,父母是我們所具有的屬性和行為的基礎。

下面以哺乳動物、狗、柯利狗之間的關系來描述“繼承”這個特性。圖1-2說明了哺乳動物、狗、柯利狗之間的繼承關系。哺乳動物是一種熱血、有毛發、用奶哺育幼仔的動物;狗是有犬牙、食肉、特定的骨骼結構、群居的哺乳動物;柯利狗是尖鼻子、具有紅白相間的顏色、適合放牧的狗。在繼承鏈中,每個類繼承了它前一個類的所有特性。例如,狗具有哺乳動物的所有特性,同時還具有區別于其他哺乳動物如貓、大象等的特征。圖中從下到上的繼承關系是:柯利狗是狗,狗是哺乳動物。“柯利狗”類繼承了“狗”類的特性,“狗”類繼承了“哺乳動物”類的特性。

圖1-2 哺乳動物、狗、柯利狗之間的繼承關系

從面向對象程序設計的角度出發,繼承所表達的是對象類之間相關的關系。這種關系使得某一類可以繼承另外一個類的特征和能力。

若類之間具有繼承關系,則它們之間具有下列幾個特性:

(1)類間具有共享特征(包括數據和操作代碼的共享)。

(2)類間具有差別或新增部分(包括非共享的數據和操作代碼)。

(3)類間具有層次結構。

假設有兩個類A和B,若類B繼承類A,則類B包含了類A的特征(包括數據和操作),同時也可以加入自己所特有的新特性。這時,稱被繼承類A為基類或父類;而稱繼承類B為A的派生類或子類。同時,還可以說,類B是從類A中派生出來的。

如果類B是類A的派生類,那么在構造類B時,不必描述類B的所有特征,只需讓它繼承類A的特征,然后描述與基類A不同的那些特性。也就是說,類B的特征由繼承來的和新添加的兩部分特征構成。

如果類B是從類A派生出來,而類C又是從類B派生出來的,那么就構成了類的層次。這樣,又有了直接基類和間接基類的概念。類A是類B的直接基類,是類C的間接基類。類C不但繼承它的直接基類的所有特性,還繼承它的所有間接基類的特征。

具體地說,繼承機制允許派生類繼承基類的數據和操作(即數據成員和成員函數),也就是說,允許派生類使用基類的數據和操作。同時,派生類還可以增加新的操作和數據。

如果沒有繼承機制,每次的軟件開發都要從“一無所有”開始,類的開發者們在構造類時,各自為政,使類與類之間沒有什么聯系,分別是一個個獨立的實體。繼承使程序不再是毫無關系的類的堆砌,而是具有良好的結構。

采用繼承的方法可以很方便地利用一個已有的類建立一個新的類,這就可以重用已有軟件中的一部分甚至大部分,在派生類中只需描述其基類中沒有的數據和操作。這樣,就避免了公用代碼的重復開發,增加了程序的可重用性,減少了代碼和數據的冗余,大大節省了編程的工作量,這就是常說的“軟件重用”思想。同時,在描述派生類時,程序員還可以覆蓋基類的一些操作,或修改和重定義基類中的操作。具體的實現方法將在以后進行詳細介紹。

從繼承源來分,繼承分為單繼承和多繼承。

單繼承是指每個派生類只直接繼承了一個基類的特征。前面介紹的動物鏈,就是一個單繼承的實例。

單繼承并不能解決繼承中的所有問題。例如,小孩喜歡的玩具車既繼承了車的一些特性,又繼承了玩具的一些特征。玩具車與玩具、車之間就形成了多繼承的關系。

多繼承是指多個基類派生出一個派生類的繼承關系。多繼承的派生類直接繼承了多于一個基類的特征。

4.多態

多態(polymorphism)也是面向對象程序設計的重要特性。在現實世界中,多態性經常出現。假設一輛汽車停在了屬于別人的車位,司機可能會聽到這樣的要求:“請把你的車挪開。”司機在聽到請求后,所做的工作應該是把車開走。在家里,一把凳子擋住了孩子的去路,他可能會請求媽媽:“請把凳子挪開。”媽媽過去搬起凳子,放在一邊。在這兩件事情中,司機和媽媽的工作都是“挪開”一樣東西,但是他們在聽到請求以后的行為是截然不同的,這就是現實世界中的多態性。對于“挪開”這個請求,還可以有更多的行為與之對應。“挪開”從字面上看是相同的,但由于作用的對象不同,操作的方法就不同。

面向對象程序設計借鑒了現實世界的多態性。面向對象系統的多態性是指不同的對象收到相同的消息時產生多種不同的行為方式。例如,有一個窗口(Window)類對象,還有一個汽車(Car)類對象,對它們發出“移動”的消息,“移動”操作在Window類對象和Car類對象上可以有不同的行為。

C++支持兩種多態性,即編譯時的多態性和運行時的多態性。編譯時的多態性是通過重載來實現的,運行時的多態性是通過虛函數來實現的。

重載一般包括函數重載和運算符重載。函數重載是指一個標識符可同時用于為多個函數命名,而運算符重載是指一個運算符可同時用于多種運算。也就是說,相同名字的函數或運算符在不同的場合可以表現出不同的行為。下面給出一個函數重載的例子。

在此,重載了3個函數,名字都是Print()。它們有各自不同的功能,分別用“語句段1”“語句段2”“語句段3”中的語句實現,在此略去了語句的細節。這3個函數的函數名相同,但函數實現的操作不同。那么,當收到要求使用Print()函數的消息時,到底應該執行哪一個函數呢?這就要看消息傳遞時函數實參的類型是什么,根據實參的類型來調用不同的同名函數。例如,發送的消息是Print(20),則執行的是“語句段1”;發送的消息是Print(12.34),則執行的是“語句段2”;發送的消息是Print("welcome"),則執行的是“語句段3”。

使用重載可以使程序員在只知道操作的一般含義、而不知道操作的具體細節的情況下能夠正確地調用某個函數,減少了程序員記憶操作名字的負擔。

如果不能使用重載,我們必須為不同函數確定不同的函數名,如PrintInteger()和Printdouble()等。程序員將需要記憶很多不同的函數名,增加了程序員的負擔。

由于虛函數的概念略為復雜,并且涉及C++的語法細節,將在第6章再進一步討論。

多態性增強了軟件的靈活性和重用性,為軟件的開發與維護提供了極大的便利。尤其是采用了虛函數和動態連編機制后,允許用戶以更為明確、易懂的方式去建立通用的軟件。

主站蜘蛛池模板: 新昌县| 富源县| 宣武区| 丽江市| 九龙县| 永平县| 玉龙| 广宁县| 易门县| 辉县市| 温州市| 如东县| 邹城市| 贵定县| 扎鲁特旗| 和田县| 年辖:市辖区| 科技| 肇州县| 山丹县| 临沂市| 巧家县| 冕宁县| 广西| 驻马店市| 府谷县| 大余县| 曲阜市| 永新县| 和林格尔县| 嘉荫县| 突泉县| 龙泉市| 阿坝县| 都昌县| 准格尔旗| 安岳县| 邵武市| 奎屯市| 泰顺县| 綦江县|