(轉(zhuǎn)載)C++教程網(wǎng)www.cppcourse.com
面向?qū)ο蟮某绦蛟O(shè)計(jì)方法要求語(yǔ)言必須具備抽象、封裝、繼承和多態(tài)性這幾個(gè)關(guān)鍵要素。
面向?qū)ο蟪绦蛟O(shè)計(jì),是通過(guò)為數(shù)據(jù)和代碼建立分塊的內(nèi)存區(qū)域,以便提供對(duì)程序進(jìn)行模塊化的一種程序設(shè)計(jì)方法。對(duì)象是計(jì)算機(jī)內(nèi)存中的一塊區(qū)域,通過(guò)將內(nèi)存分塊,每個(gè)模塊(即對(duì)象)在功能上相互之間保持相對(duì)獨(dú)立。
這些內(nèi)存模塊中不但存儲(chǔ)數(shù)據(jù),而且也存儲(chǔ)代碼,這對(duì)保證對(duì)象是受保護(hù)的這一點(diǎn)很重要,只有對(duì)象中的代碼才可以訪問(wèn)存儲(chǔ)于這個(gè)對(duì)象中的數(shù)據(jù),這清楚地限定了對(duì)象所具有的功能(即一個(gè)對(duì)象在一個(gè)軟件中所能起到的作用),并使對(duì)象保護(hù)它自己不受未知的外部其它的事件的影響,從而使自己的數(shù)據(jù)和功能不會(huì)因此遭到破壞。
在面向?qū)ο蟮某绦蛑校瑢?duì)象之間可以通過(guò)函數(shù)調(diào)用實(shí)現(xiàn)相互通信。一個(gè)對(duì)象可以調(diào)用另一個(gè)對(duì)象的函數(shù),處于對(duì)象外部的代碼就沒(méi)有機(jī)會(huì)通過(guò)直接修改對(duì)象的內(nèi)存區(qū)域。當(dāng)對(duì)象的一個(gè)函數(shù)被調(diào)用時(shí),對(duì)象執(zhí)行其內(nèi)部代碼來(lái)響應(yīng)這個(gè)調(diào)用,這使tb對(duì)象呈現(xiàn)出一定的行為。行為及其結(jié)果就是該對(duì)象的功能。對(duì)象被視為能做出動(dòng)作的實(shí)體,動(dòng)作在對(duì)象相互作用時(shí)被激發(fā),換句話說(shuō),對(duì)象就像在宿主計(jì)算機(jī)上擁有數(shù)據(jù)和代碼,并能相互通信的具有特定功能的一臺(tái)較小的計(jì)算機(jī)。
抽象
面向?qū)ο蠊膭?lì)程序員以抽象的觀點(diǎn)看待程序,即程序是由一組抽象的對(duì)象組成的。另一方面,我們又可以將一組對(duì)象的共同特征進(jìn)一步抽象出來(lái),從面形成“類(lèi)”的概念。
抽象是一種從一般的觀點(diǎn)看待事物的方法,它要求程序員集中于事物的本質(zhì)特征,而不是具體細(xì)節(jié)或具體實(shí)現(xiàn)。面向?qū)ο蠊膭?lì)程序員以抽象的觀點(diǎn)看待程序,也就是說(shuō)程序是一組抽象的對(duì)象-類(lèi)組成的(嚴(yán)格講,C++程序不是純面向?qū)ο蟮?,因?yàn)槌绦蛑羞€有像main這樣的全局函數(shù))。程序從一組對(duì)象為起來(lái),抽取公共的行為放入到一個(gè)類(lèi)中,這是抽象分類(lèi)的觀點(diǎn),不同類(lèi)的對(duì)象具有不同的行為。
類(lèi)的概念來(lái)源于人們認(rèn)識(shí)自然、認(rèn)識(shí)社會(huì)的過(guò)程。在這一過(guò)程中,人們主要使用兩種方法:由特殊到一般的歸納法和由一般到特殊的演繹法。在歸納的過(guò)程中,我們從一個(gè)個(gè)具體的事物中把共同的特征抽取出來(lái),形成一個(gè)一般的概念,這就是“歸類(lèi)”;在演繹的過(guò)程中,我們又把同類(lèi)的事物,根據(jù)不同的特征分成不同的小類(lèi),這又是“分類(lèi)”。對(duì)于一個(gè)具體的類(lèi),它有許多具體的個(gè)體,我們就管這些個(gè)體叫做“對(duì)象”。
舉個(gè)例子,“人”是一個(gè)類(lèi),具有“直立行走、會(huì)使用工具”等一些區(qū)別于其它事物的共同特征;而張三、李四、王五等一個(gè)個(gè)具體的人,就是“人”這個(gè)類(lèi)的一個(gè)個(gè)“對(duì)象”。
封裝
所謂數(shù)據(jù)封裝,就是將一組數(shù)據(jù)和與這組數(shù)據(jù)相關(guān)的操作集合組裝在一起,形成一個(gè)能動(dòng)的實(shí)體,也就是對(duì)象。在這種情況下,用戶(hù)是不可以直接操作數(shù)據(jù)的,他必須通過(guò)和數(shù)據(jù)相關(guān)的操作來(lái)訪問(wèn)數(shù)據(jù)。換句話說(shuō),數(shù)據(jù)封裝就是給數(shù)據(jù)提供了與外界聯(lián)系的標(biāo)準(zhǔn)接口,無(wú)論是誰(shuí),只有通過(guò)這些接口,使用規(guī)范的方式,才能訪問(wèn)這些數(shù)據(jù)。同時(shí),由于客戶(hù)端總是和接口打交道,他也就不必要了解數(shù)據(jù)的具體細(xì)節(jié)。
由此可見(jiàn),封裝要求一個(gè)對(duì)象應(yīng)具備明確的功能,并具有接口以便和其它對(duì)象相互作用。同時(shí),對(duì)象的內(nèi)部實(shí)現(xiàn)(代碼和數(shù)據(jù))是受保護(hù)的,外界不能訪問(wèn)它們,只有局部于對(duì)象的代碼才可以訪問(wèn)對(duì)象的內(nèi)部數(shù)據(jù)。對(duì)象的內(nèi)部數(shù)據(jù)結(jié)構(gòu)的不可訪問(wèn)性稱(chēng)為數(shù)據(jù)隱藏。封裝使得一個(gè)對(duì)象可以像一個(gè)部件一樣用在各種程序中,而不用擔(dān)心對(duì)象的功能受到影響。
早期的軟件設(shè)計(jì)方法,把數(shù)據(jù)和程序混在一起,結(jié)構(gòu)化很差,被細(xì)稱(chēng)為“一碗面條”的編程方法。在這一階段程序的可讀性與可維護(hù)性都很差,于是產(chǎn)生了“軟件危機(jī)”,為了解除這種危機(jī)便提出了結(jié)構(gòu)化程序設(shè)計(jì)。在結(jié)構(gòu)化程序設(shè)計(jì)里,雖然程序被分為不同的模塊,以便大大減少不同模塊之間的相互作用,但數(shù)據(jù)仍然屬于整個(gè)程序的。這就又存在著這樣一個(gè)問(wèn)題:一方面,程序員在設(shè)計(jì)每一個(gè)模塊的時(shí)候,都要或多或少地作全局考慮,模塊與模塊之間的耦合度相對(duì)太高了,勢(shì)必增加不同模塊的程序員之間溝通所帶來(lái)的工作量;另一方面,在某地方對(duì)數(shù)據(jù)的改動(dòng),有可能又對(duì)整個(gè)程序產(chǎn)生難以預(yù)料的影響。隨著軟件工程的進(jìn)一步發(fā)展,軟件越來(lái)越大,數(shù)據(jù)越來(lái)越多,這個(gè)問(wèn)題也越來(lái)越突出。
數(shù)據(jù)封裝的提出,就是為了解決這一問(wèn)題。它一方面使得程序員在設(shè)計(jì)程序時(shí)可以專(zhuān)注于自己的對(duì)象,“各人自掃門(mén)前雪,莫管他人瓦上霜”,同時(shí)也切斷了不同模塊之間數(shù)據(jù)的非法使用,減少了出錯(cuò)的可能性。
繼承
所謂繼承是指一個(gè)對(duì)象可以獲得另一個(gè)對(duì)象的特性的機(jī)制,它支持層次類(lèi)這一概念。例如:紅蘋(píng)果屬于蘋(píng)果類(lèi),而蘋(píng)果類(lèi)又屬于水果類(lèi)。通過(guò)繼承,低層的類(lèi)只需定義特定于它的特征,而共享高層類(lèi)中的特征。
多態(tài)
不同的對(duì)象可以調(diào)用相同名稱(chēng)的函數(shù),并可導(dǎo)致完全不同的行為的現(xiàn)象稱(chēng)為多態(tài)性。利用多態(tài)性,程序中只需進(jìn)行一般形式的函數(shù)調(diào)用,函數(shù)的實(shí)現(xiàn)細(xì)節(jié)留給接受函數(shù)調(diào)用的對(duì)象。這大大提高了我們解決復(fù)雜問(wèn)題的能力。例如繪制三角形與繪制正方形所調(diào)用的繪制函數(shù)其效果肯定是不同的,但我們可以設(shè)計(jì)一個(gè)公共的Draw()函數(shù)代表繪制,而不同對(duì)象的繪制圖形的具體細(xì)節(jié)則分別由具體對(duì)象負(fù)責(zé)實(shí)現(xiàn)。