百科解釋
目錄·概述·基本理論·OOP名詞釋意·面向?qū)ο蟮恼Z(yǔ)言·歷史 面向?qū)ο蟪绦蛟O(shè)計(jì)(英語(yǔ):Object-oriented programming,縮寫(xiě):OOP),指一種程序設(shè)計(jì)范型,同時(shí)也是一種程序開(kāi)發(fā)的方法論。它將對(duì)象作為程序的基本單元,將程序和數(shù)據(jù)封裝其中,以提高軟件的重用性、靈活性和擴(kuò)展性。[1] 當(dāng)我們提到面向?qū)ο蟮臅r(shí)候,它不僅指一種程序設(shè)計(jì)方法。它更多意義上是一種程序開(kāi)發(fā)方式。在這一方面,我們必須了解更多關(guān)于面向?qū)ο笙到y(tǒng)分析和面向?qū)ο笤O(shè)計(jì)(Object Oriented Design,簡(jiǎn)稱OOD)方面的知識(shí)。 概述 面向?qū)ο蟪绦蛟O(shè)計(jì)的雛形,早在1960年的Simula語(yǔ)言中即可發(fā)現(xiàn),當(dāng)時(shí)的程序設(shè)計(jì)領(lǐng)域正面臨著一種危機(jī):在軟硬件環(huán)境逐漸復(fù)雜的情況下,軟件如何得到良好的維護(hù)?面向?qū)ο蟪绦蛟O(shè)計(jì)在某種程度上通過(guò)強(qiáng)調(diào)可重復(fù)性解決了這一問(wèn)題。20世紀(jì)70年代的SmallTalk語(yǔ)言在面向?qū)ο蠓矫婵胺Q經(jīng)典——以至于30年后的今天依然將這一語(yǔ)言視為面向?qū)ο笳Z(yǔ)言的基礎(chǔ)。 面向?qū)ο蟪绦蛟O(shè)計(jì)可以被視作一種在程序中包含各種獨(dú)立而又互相調(diào)用的單位和對(duì)象的思想,這與傳統(tǒng)的思想剛好相反:傳統(tǒng)的面向過(guò)程程序設(shè)計(jì)主張將程序看作一系列函數(shù)的集合,或者直接就是一系列對(duì)電腦下達(dá)的指令。面向?qū)ο蟪绦蛟O(shè)計(jì)中的每一個(gè)對(duì)象都應(yīng)該能夠接受數(shù)據(jù)、處理數(shù)據(jù)并將數(shù)據(jù)傳達(dá)給其它對(duì)象,因此它們都可以被看作一個(gè)小型的“機(jī)器”,或者說(shuō)是負(fù)有責(zé)任的角色。 目前已經(jīng)被證實(shí)的是,面向?qū)ο蟪绦蛟O(shè)計(jì)推廣了程序的靈活性和可維護(hù)性,并且在大型項(xiàng)目設(shè)計(jì)中廣為應(yīng)用。 此外,支持者聲稱面向?qū)ο蟪绦蛟O(shè)計(jì)要比以往的做法更加便于學(xué)習(xí),因?yàn)樗軌蜃屓藗兏?jiǎn)單地設(shè)計(jì)并維護(hù)程序,使得程序更加便于分析、設(shè)計(jì)、理解。反對(duì)者在某些領(lǐng)域?qū)Υ擞枰苑裾J(rèn)。 基本理論 一項(xiàng)由 Deborah J. Armstrong 進(jìn)行的長(zhǎng)達(dá)40年之久的計(jì)算機(jī)著作調(diào)查顯示出了一系列面向?qū)ο蟪绦蛟O(shè)計(jì)的基本理論。它們是: 類 類(Class)定義了一件事物的抽象特點(diǎn)。通常來(lái)說(shuō),類定義了事物的屬性和它可以做到的(它的行為)。舉例來(lái)說(shuō),“狗”這個(gè)類會(huì)包含狗的一切基礎(chǔ)特征,例如它的孕育、毛皮顏色和吠叫的能力。類可以為程序提供模版和結(jié)構(gòu)。一個(gè)類的方法和屬性被稱為“成員”。 我們來(lái)看一段偽代碼: <code>類狗 開(kāi)始 私有成員: 孕育 毛皮顏色 公有成員: 吠叫() 結(jié)束 </code> 在這串代碼中,我們聲明了一個(gè)類,這個(gè)類具有一些狗的基本特征。關(guān)于公有成員和私有成員,請(qǐng)參見(jiàn)下面的繼承性一節(jié)。 對(duì)象 對(duì)象(Object)是類的實(shí)例。例如,“狗”這個(gè)類列舉狗的特點(diǎn),從而使這個(gè)類定義了世界上所有的狗。而萊絲這個(gè)對(duì)象則是一條具體的狗,它的屬性也是具體的。狗有皮毛顏色,而萊絲的皮毛顏色是棕白色的。因此,萊絲就是狗這個(gè)類的一個(gè)實(shí)例。一個(gè)具體對(duì)象屬性的值被稱作它的“狀態(tài)”。 假設(shè)我們已經(jīng)在上面定義了狗這個(gè)類,我們就可以用這個(gè)類來(lái)定義對(duì)象: 定義萊絲是狗 萊絲.毛皮顏色:=棕白色 萊絲.吠叫() 我們無(wú)法讓狗這個(gè)類去吠叫,但是我們可以讓對(duì)象“萊絲”去吠叫,正如狗可以吠叫,但沒(méi)有具體的狗就無(wú)法吠叫。 方法 方法(Method)是一個(gè)類能做的事情,但方法并沒(méi)有去做這件事。作為一條狗,萊絲是會(huì)吠叫的,因此“吠叫()”就是它的一個(gè)方法。與此同時(shí),它可能還會(huì)有其它方法,例如“坐下()”,或者“吃()”。 對(duì)一個(gè)具體對(duì)象的方法進(jìn)行調(diào)用并不影響其它對(duì)象,正如所有的狗都會(huì)叫,但是你讓一條狗叫不代表所有的狗都叫。 如下例: 定義萊絲是狗 定義泰爾是狗 萊絲.吠叫() 則泰爾是不會(huì)吠叫的,因?yàn)檫@里的吠叫只是對(duì)對(duì)象“萊絲”進(jìn)行的。 消息傳遞機(jī)制 一個(gè)對(duì)象通過(guò)接受消息、處理消息、傳出消息或使用其他類的方法來(lái)實(shí)現(xiàn)一定功能,這叫做消息傳遞機(jī)制(Message Passing)。 繼承性 繼承性(Inheritance)是指,在某種情況下,一個(gè)類會(huì)有“子類”。子類比原本的類(稱為父類)要更加具體化,例如,“狗”這個(gè)類可能會(huì)有它的子類“牧羊犬”和“吉娃娃犬”。在這種情況下,“萊絲”可能就是牧羊犬的一個(gè)實(shí)例。子類會(huì)繼承父類的屬性和行為,并且也可包含它們自己的。我們假設(shè)“狗”這個(gè)類有一個(gè)方法叫做“吠叫()”和一個(gè)屬性叫做“毛皮顏色”。它的子類(前例中的牧羊犬和吉娃娃犬)會(huì)繼承這些成員。這意味著程序員只需要將相同的代碼寫(xiě)一次。 在偽代碼中我們可以這樣寫(xiě): 類牧羊犬:繼承狗 定義萊絲是牧羊犬 萊絲.吠叫() /* 注意這里調(diào)用的是狗這個(gè)類的吠叫屬性。 */ 回到前面的例子,“牧羊犬”這個(gè)類可以繼承“毛皮顏色”這個(gè)屬性,并指定其為棕白色。而“吉娃娃犬”則可以繼承“吠叫()”這個(gè)方法,并指定它的音調(diào)高于平常。子類也可以加入新的成員,例如,“吉娃娃犬”這個(gè)類可以加入一個(gè)方法叫做“顫抖()”。設(shè)若用“牧羊犬”這個(gè)類定義了一個(gè)實(shí)例“萊絲”,那么萊絲就不會(huì)顫抖,因?yàn)檫@個(gè)方法是屬于吉娃娃犬的,而非牧羊犬。事實(shí)上,我們可以把繼承理解為“是”。例如,萊絲“是”牧羊犬,牧羊犬“是”狗。因此,萊絲既繼承了牧羊犬的屬性,又繼承了狗的屬性。 我們來(lái)看偽代碼: 類吉娃娃犬:繼承狗 開(kāi)始 公有成員: 顫抖() 結(jié)束 類牧羊犬:繼承狗 定義萊絲是牧羊犬 萊絲.顫抖() /* 錯(cuò)誤:顫抖是吉娃娃犬的成員方法。 */ 當(dāng)一個(gè)類從多個(gè)父類繼承時(shí),我們稱之為“多重繼承”。多重繼承并不總是被支持的,因?yàn)樗茈y理解,又很難被好好使用。 封裝性 具備封裝性(Encapsulation)的面向?qū)ο蟪绦蛟O(shè)計(jì)隱藏了某一方法的具體執(zhí)行步驟,取而代之的是通過(guò)消息傳遞機(jī)制傳送消息給它。因此,舉例來(lái)說(shuō),“狗”這個(gè)類有”吠叫()”的方法,這一方法定義了狗具體該通過(guò)什么方法吠叫。但是,萊絲的朋友蒂米并不需要知道它到底如何吠叫。 從實(shí)例來(lái)看: /* 一個(gè)面向過(guò)程的程序會(huì)這樣寫(xiě): */ 定義萊絲 萊絲.設(shè)置音調(diào)(5) 萊絲.吸氣() 萊絲.吐氣() /* 而當(dāng)狗的吠叫被封裝到類中,任何人都可以簡(jiǎn)單地使用: */ 定義萊絲是狗 萊絲.吠叫() 封裝是通過(guò)限制只有特定類的實(shí)例可以訪問(wèn)這一特定類的成員,而它們通常利用接口實(shí)現(xiàn)消息的傳入傳出。舉個(gè)例子,接口能確保幼犬這一特征只能被賦予狗這一類。通常來(lái)說(shuō),成員會(huì)依它們的訪問(wèn)權(quán)限被分為3種:公有成員、私有成員以及保護(hù)成員。有些語(yǔ)言更進(jìn)一步:Java可以限制同一包內(nèi)不同類的訪問(wèn);C#和VB.NET保留了為類的成員聚集準(zhǔn)備的關(guān)鍵字:internal(C#)和Friend(VB.NET);Eiffel語(yǔ)言則可以讓用戶指定哪個(gè)類可以訪問(wèn)所有成員。 多態(tài)性 多態(tài)性(Polymorphism)指方法在不同的類中調(diào)用可以實(shí)現(xiàn)的不同結(jié)果。因此,2個(gè)甚至更多的類可以對(duì)同一消息作出不同的反應(yīng)。舉例來(lái)說(shuō),狗和雞都有“叫()”這一方法,但是調(diào)用狗的“叫()”,狗會(huì)吠叫;調(diào)用雞的“叫()”,雞則會(huì)啼叫。 我們將它體現(xiàn)在偽代碼上: 類狗 開(kāi)始 公有成員: 叫() 開(kāi)始 吠叫() 結(jié)束 結(jié)束 類雞 開(kāi)始 公有成員: 叫() 開(kāi)始 啼叫() 結(jié)束 結(jié)束 定義萊絲是狗 定義魯斯特是雞 萊絲.叫() 魯斯特.叫() 這樣,同樣是叫,萊絲和魯斯特做出的反應(yīng)將大不相同。多態(tài)性的概念可以用在運(yùn)算符重載上,本文不再贅述。 抽象性 抽象(Abstraction)是簡(jiǎn)化復(fù)雜的現(xiàn)實(shí)問(wèn)題的途徑,它可以為具體問(wèn)題找到最恰當(dāng)?shù)念惗x,并且可以在最恰當(dāng)?shù)睦^承級(jí)別解釋問(wèn)題。舉例說(shuō)明,萊絲在大多數(shù)時(shí)候都被當(dāng)作一條狗,但是如果想要讓它做牧羊犬做的事,你完全可以調(diào)用牧羊犬的方法。如果狗這個(gè)類還有動(dòng)物的父類,那么你完全可以視萊絲為一個(gè)動(dòng)物。 OOP名詞釋意 編程范型 對(duì)于OOP的準(zhǔn)確定義及其本意存在著不少爭(zhēng)論。 通常,OOP被理解為一種將程序分解為封裝數(shù)據(jù)及相關(guān)操作的模塊而進(jìn)行的編程方式。有別于其它編程方式,OOP中的與某數(shù)據(jù)類型相關(guān)的一系列操作都被有機(jī)地封裝到該數(shù)據(jù)類型當(dāng)中,而非散放于其外,因而OOP中的數(shù)據(jù)類型不僅有著狀態(tài),還有著相關(guān)的行為。OOP理論,及與之同名的OOP實(shí)踐相結(jié)合創(chuàng)造出了新的一個(gè)編程架構(gòu);OOP思想被廣泛認(rèn)為是非常有用的,以致一套新的編程范型被創(chuàng)造了出來(lái)。(其它的編程范型例如函數(shù)式編程或過(guò)程序編程專注于程序運(yùn)行的過(guò)程,而邏輯編程專注于引發(fā)程序代碼執(zhí)行的斷言) 對(duì)面向模擬系統(tǒng)的語(yǔ)言(如:SIMULA 67)的研究及對(duì)高可靠性系統(tǒng)架構(gòu)(如:高性能操作系統(tǒng)和CPU的架構(gòu))的研究最終導(dǎo)致了OOP的誕生。 一些專家認(rèn)為Object-Orientation中的Object的本意來(lái)自于其在語(yǔ)法領(lǐng)域的意義,即應(yīng)將其理解為“賓語(yǔ)”或“操作對(duì)象”,而非一般的“對(duì)象”或“對(duì)象”。我們所見(jiàn)到的軟件的運(yùn)行請(qǐng)求通常都是Subject-Oriented的,即“面向主語(yǔ)的”或“面向操作者的”,然而這樣將使得對(duì)操作者對(duì)象的設(shè)計(jì)變得困難而復(fù)雜。有鑒于此,部分研究人員開(kāi)始了對(duì)“面向操作對(duì)象”的思考。這又一次產(chǎn)生了新的編程范型,這是前邊提到的“面向操作者”的思考模式的一項(xiàng)革新。 依照“面向操作對(duì)象”的原則,在程序語(yǔ)句中的動(dòng)詞應(yīng)該被劃分到操作對(duì)象的類型之中,而與該動(dòng)詞請(qǐng)求相關(guān)的邏輯關(guān)系也就因此將在操作對(duì)象中處理。以下是采用“面向操作對(duì)象”的方式翻譯“面向操作者”的一些例子: 面向操作者:銷售系統(tǒng)保存交易記錄。 面向操作對(duì)象:交易記錄在接受到銷售系統(tǒng)的一條請(qǐng)求消息后將自身保存。 面向操作者:銷售系統(tǒng)打印收據(jù)。 面向操作對(duì)象:收據(jù)在接收到銷售系統(tǒng)的一條請(qǐng)求消息后將自身打印。 面向?qū)ο蟮恼Z(yǔ)言 支持部分或絕大部分面向?qū)ο筇匦缘恼Z(yǔ)言即可稱為基于對(duì)象的或面向?qū)ο蟮恼Z(yǔ)言。 早期,完全面向?qū)ο蟮恼Z(yǔ)言主要包括Smalltalk等語(yǔ)言,目前較為流行的語(yǔ)言中有Java、C#、Eiffel等。隨著軟件工業(yè)的發(fā)展,比較早的面向過(guò)程的語(yǔ)言在近些年的發(fā)展中也紛紛吸收了許多面向?qū)ο蟮母拍,比如C->C++,BASIC->Visual Basic->Visual Basic .NET,Pascal->Object Pascal,Ada->Ada95。 歷史 對(duì)象和實(shí)例的最早概念出自麻省理工大學(xué)的PDP-1系統(tǒng)。這一系統(tǒng)大概是capability based architecture的最早示例。另一個(gè)早期的事例是1963年Ivan Sutherland開(kāi)發(fā)的Sketchpad;但是,這并非是一種編程思想,而只是一個(gè)程序。 對(duì)象最早在20世紀(jì)60年代的Simula 67中被引入程序設(shè)計(jì)中。Simula這一語(yǔ)言是Ole-Johan Dahl和Kristen Nygaard在奧斯陸計(jì)算機(jī)中心為模擬環(huán)境而設(shè)計(jì)的。(據(jù)說(shuō),他們是為了模擬船只而設(shè)計(jì)的這種語(yǔ)言,并且對(duì)不同船只間屬性的相互影響感興趣。他們將不同的船只歸納為不同的類,而每一個(gè)對(duì)象,基于它的類,可以定義它自己的屬性和行為。)這種辦法是分析式程序的最早概念體現(xiàn)。在分析式程序中,我們將真實(shí)世界的對(duì)象映射到抽象的對(duì)象,這叫做“模擬”。Simula不僅引入了“類”的概念,還應(yīng)用了實(shí)例這一思想——這可能是這些概念的最早應(yīng)用。 20世紀(jì)70年代施樂(lè)PARC研究所發(fā)明的Smalltalk語(yǔ)言將面向?qū)ο蟪绦蛟O(shè)計(jì)的概念定義為,在基礎(chǔ)運(yùn)算中,對(duì)對(duì)象和消息的廣泛應(yīng)用。Smalltalk的創(chuàng)建者深受Simula 67的主要思想影響,但Smalltalk中的對(duì)象是完全動(dòng)態(tài)的——它們可以被創(chuàng)建、修改并銷毀,這與Simula中的靜態(tài)對(duì)象有所區(qū)別。此外,Smalltalk還引入了繼承性的思想,它因此一舉超越了不可創(chuàng)建實(shí)例的程序設(shè)計(jì)模型和不具備繼承性的Simula。 此外,Simula 67的思想亦被應(yīng)用在許多不同的語(yǔ)言,如Lisp、Pascal。 面向?qū)ο蟪绦蛟O(shè)計(jì)在80年代成為了一種主導(dǎo)思想,這主要應(yīng)歸功于C++——C語(yǔ)言的擴(kuò)充版。在圖形用戶界面(GUI)日漸崛起的情況下,面向?qū)ο蟪绦蛟O(shè)計(jì)很好地適應(yīng)了潮流。GUI和面向?qū)ο蟪绦蛟O(shè)計(jì)的緊密關(guān)聯(lián)在Mac OS X中可見(jiàn)一斑。Mac OS X是由面向?qū)ο驝語(yǔ)言寫(xiě)成的,這一語(yǔ)言是一個(gè)仿Smalltalk的C語(yǔ)言擴(kuò)充版。面向?qū)ο蟪绦蛟O(shè)計(jì)的思想也使事件處理式的程序設(shè)計(jì)更加廣泛被應(yīng)用(雖然這一概念并非僅存在于面向?qū)ο蟪绦蛟O(shè)計(jì))。一種說(shuō)法是,GUI的引入極大地推動(dòng)了面向?qū)ο蟪绦蛟O(shè)計(jì)的發(fā)展。 在ETH Zürich(英文),Niklaus Wirth 和他的同事們對(duì)抽象數(shù)據(jù)和模塊化程序設(shè)計(jì)進(jìn)行了調(diào)查。Modula-2將這些都包括了進(jìn)去,而Oberon則包括了一種特殊的面向?qū)ο蠓椒ā煌赟malltalk與C++。 面向?qū)ο蟮奶匦砸脖患尤肓水?dāng)時(shí)較為流行的語(yǔ)言:Ada、BASIC、Lisp、Fortran、Pascal以及種種。由于這些語(yǔ)言最初并沒(méi)有面向?qū)ο蟮脑O(shè)計(jì),故而這種糅合常常會(huì)導(dǎo)致兼容性和維護(hù)性的問(wèn)題。與之相反的是,“純正的”面向?qū)ο笳Z(yǔ)言卻缺乏一些程序員們賴以生存的特性。在這一大環(huán)境下,開(kāi)發(fā)新的語(yǔ)言成為了當(dāng)務(wù)之急。作為先行者,Eiffel成功地解決了這些問(wèn)題,并成為了當(dāng)時(shí)較受歡迎的語(yǔ)言。 在過(guò)去的幾年中,Java語(yǔ)言成為了廣為應(yīng)用的語(yǔ)言,除了它與C和C++語(yǔ)法上的近似性。Java的可移植性是它的成功中不可磨滅的一步,因?yàn)檫@一特性,已吸引了龐大的程序員群的投入。 近日,一些既支持面向?qū)ο蟪绦蛟O(shè)計(jì),又支持面向過(guò)程程序設(shè)計(jì)的語(yǔ)言悄然浮出水面。它們中的佼佼者有Python、Ruby等等. 正如面向過(guò)程程序設(shè)計(jì)使得結(jié)構(gòu)化程序設(shè)計(jì)的技術(shù)得以提升,現(xiàn)代的面向?qū)ο蟪绦蛟O(shè)計(jì)方法使得對(duì)設(shè)計(jì)模式的用途、契約式設(shè)計(jì)和建模語(yǔ)言(如UML)技術(shù)也得到了一定提升。 腳本中的OOP 近年來(lái),面向過(guò)程程序設(shè)計(jì)越發(fā)流行于腳本語(yǔ)言。Python和Ruby是建立在OOP原理的腳本語(yǔ)言,Perl和PHP亦分別在Perl 5和PHP 4時(shí)加入面向過(guò)程特性。
移動(dòng)通信網(wǎng) | 通信人才網(wǎng) | 更新日志 | 團(tuán)隊(duì)博客 | 免責(zé)聲明 | 關(guān)于詞典 | 幫助