面向?qū)ο蟪绦蛟O(shè)計(jì)
特征
面向?qū)ο蟪绦蚓幊痰亩x是使用“對象”來做設(shè)計(jì),但并非所有的編程語言都直接支持“面向?qū)ο蟪绦蚓幊獭毕嚓P(guān)技術(shù)與結(jié)構(gòu)。對于OOP的準(zhǔn)確定義及其本意存在著不少爭論。通常,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)造了出來。(其它的編程范型例如函數(shù)式編程或過程式編程專注于程序運(yùn)行的過程,而邏輯編程專注于引發(fā)程序代碼執(zhí)行的斷言)。對面向模擬系統(tǒng)的語言(如:SIMULA 67)的研究及對高可靠性系統(tǒng)架構(gòu)(如:高性能操作系統(tǒng)和CPU的架構(gòu))的研究最終導(dǎo)致了OOP的誕生。其中由Deborah J. Armstrong進(jìn)行的長達(dá)40年之久的計(jì)算機(jī)著作調(diào)查中,顯示出了一系列面向?qū)ο蟪绦蛟O(shè)計(jì)的基本理論。面向?qū)ο蟪绦蛱卣鞅粭l列如下
分享非面向?qū)ο蟪绦蚯吧碚Z言
面向?qū)ο蟪绦蛟O(shè)計(jì)通常共享高級編程語言的低級功能??捎糜诮?gòu)一個(gè)程序的基本工具包括:
變量能存儲一些內(nèi)置類型的信息如整數(shù)與字符,也有些是數(shù)據(jù)結(jié)構(gòu)像是字符串、串列與散列表等包含內(nèi)置或復(fù)合的變量如指針。
程序:也稱為函數(shù)、方法或例程,是指輸入數(shù)據(jù)產(chǎn)生輸出結(jié)果,現(xiàn)代語言還包含結(jié)構(gòu)化編程結(jié)構(gòu)如程序循環(huán)與條件。
類與對象
支持面向?qū)ο缶幊陶Z言通常利用繼承其他類達(dá)到代碼重用和可擴(kuò)展性的特性。而類有兩個(gè)主要的概念:
類(Class):定義了一件事物的抽象特點(diǎn)。類的定義包含了數(shù)據(jù)的形式以及對數(shù)據(jù)的操作。
對象:是類的實(shí)例。
其中類別(Class)定義了一件事物的抽象特點(diǎn)。類的定義包含了數(shù)據(jù)的形式以及對數(shù)據(jù)的操作。舉例來說,“狗”這個(gè)類會包含狗的一切基礎(chǔ)特征,即所有“狗”都共有的特征或行為,例如它的孕育、毛皮顏色和吠叫的能力。類可以為程序提供模版和結(jié)構(gòu)。一個(gè)類的方法和屬性被稱為“成員”。 我們來看一段偽代碼:
在這串代碼中,我們聲明了一個(gè)類,這個(gè)類具有一些狗的基本特征。關(guān)于公有成員和私有成員,請參見下面的繼承性一節(jié)。
對象(Object)是類的實(shí)例。對象有時(shí)會對應(yīng)到現(xiàn)實(shí)世界中的事物,舉例來說,一個(gè)圖形程序可能有圓形、矩形與畫面等對象,一個(gè)在線購物系統(tǒng)可能有購物車、顧客與產(chǎn)品等類。 。有時(shí)對象會表示更抽象的實(shí)體,比如一個(gè)被打開的文件或是一個(gè)提供美國慣用量測轉(zhuǎn)換的服務(wù)。每個(gè)對象就是一個(gè)特定類的實(shí)例(例如,名稱是“瑪麗”的對象可能是類雇員的一個(gè)實(shí)例)。程序在面向?qū)ο缶幊坍?dāng)中被視為方法,變量被視為成員或?qū)傩浴@?,“狗”這個(gè)類列舉狗的特點(diǎn),從而使這個(gè)類定義了世界上所有的狗。而萊絲這個(gè)對象則是一條具體的狗,它的屬性也是具體的。狗有皮毛顏色,而萊絲的皮毛顏色是棕白色的。因此,萊絲就是狗這個(gè)類的一個(gè)實(shí)例。一個(gè)具體對象屬性的值被稱作它的“狀態(tài)”。(系統(tǒng)給對象分配內(nèi)存空間,而不會給類分配內(nèi)存空間。這很好理解,類是抽象的系統(tǒng)不可能給抽象的東西分配空間,而對象則是具體的。)
假設(shè)我們已經(jīng)在上面定義了狗這個(gè)類,我們就可以用這個(gè)類來定義對象:
我們無法讓狗這個(gè)類去吠叫,但是我們可以讓對象“萊絲”去吠叫,正如狗可以吠叫,但沒有具體的狗就無法吠叫。
類和對象就好比是“實(shí)型”和“1.23”,“實(shí)型”是一種數(shù)據(jù)的類型,而“1.23”是一個(gè)真正的“實(shí)數(shù)”(即對象)。所有的“實(shí)數(shù)”都具有“實(shí)型”所描訴的特征,如“實(shí)數(shù)的大小”,系統(tǒng)則分配內(nèi)存給“實(shí)數(shù)”存儲具體的數(shù)值。
動態(tài)配置與消息傳遞機(jī)制
定義上動態(tài)配置是指方法會隨著實(shí)例動態(tài)的改變。而消息傳遞機(jī)制(Message Passing)是指一個(gè)對象通過接受消息、處理消息、傳出消息或使用其他類的方法來實(shí)現(xiàn)一定功能。如: 萊絲 可以通過 吠叫 引起 人 的注意,從而導(dǎo)致一系列的事發(fā)生。
封裝性
具備封裝性(Encapsulation)的面向?qū)ο蟪绦蛟O(shè)計(jì)隱藏了某一方法的具體運(yùn)行步驟,取而代之的是通過消息傳遞機(jī)制發(fā)送消息給它。封裝是通過限制只有特定類的對象可以訪問這一特定類的成員,而它們通常利用接口實(shí)現(xiàn)消息的傳入傳出。舉個(gè)例子,接口能確保幼犬這一特征只能被賦予狗這一類。通常來說,成員會依它們的訪問權(quán)限被分為3種:公有成員、私有成員以及保護(hù)成員。有些語言更進(jìn)一步:Java可以限制同一包內(nèi)不同類的訪問;C#和VB.NET保留了為類的成員聚集準(zhǔn)備的關(guān)鍵字:internal(C#)和Friend(VB.NET);Eiffel語言則可以讓用戶指定哪個(gè)類可以訪問所有成員。
具備封裝性(Encapsulation)的面向?qū)ο蟪绦蛟O(shè)計(jì)隱藏了某一方法的具體執(zhí)行步驟,取而代之的是通過消息傳遞機(jī)制傳送消息給它。因此,舉例來說,“狗”這個(gè)類有“吠叫()”的方法,這一方法定義了狗具體該通過什么方法吠叫。但是,萊絲的朋友并不知道它到底是如何吠叫的。
從實(shí)例來看:
繼承
繼承性(Inheritance)是指,在某種情況下,一個(gè)類會有“子類”。子類比原本的類(稱為父類)要更加具體化。例如,“狗”這個(gè)類可能會有它的子類“牧羊犬”和“吉娃娃犬”。在這種情況下,“萊絲”可能就是牧羊犬的一個(gè)實(shí)例。子類會繼承父類的屬性和行為,并且也可包含它們自己的。我們假設(shè)“狗”這個(gè)類有一個(gè)方法(行為)叫做“吠叫()”和一個(gè)屬性叫做“毛皮顏色”。它的子類(前例中的牧羊犬和吉娃娃犬)會繼承這些成員。這意味著程序員只需要將相同的代碼寫一次。
在偽代碼中我們可以這樣寫:
回到前面的例子,“牧羊犬”這個(gè)類可以繼承“毛皮顏色”這個(gè)屬性,并指定其為棕白色。而“吉娃娃犬”則可以繼承“吠叫()”這個(gè)方法,并指定它的音調(diào)高于平常。子類也可以加入新的成員,例如,“吉娃娃犬”這個(gè)類可以加入一個(gè)方法叫做“顫抖()”。設(shè)若用“牧羊犬”這個(gè)類定義了一個(gè)實(shí)例“萊絲”,那么萊絲就不會顫抖,因?yàn)檫@個(gè)方法是屬于吉娃娃犬的,而非牧羊犬。事實(shí)上,我們可以把繼承理解為“是”或“屬于”。萊絲“是”牧羊犬,牧羊犬“屬于”狗類。因此,萊絲既得到了牧羊犬的屬性,又繼承了狗的屬性。 我們來看偽代碼:
當(dāng)一個(gè)類從多個(gè)父類繼承時(shí),我們稱之為“多重繼承”。如一只狗既是吉娃娃犬又是牧羊犬(雖然事實(shí)上并不合邏輯)。多重繼承并不總是被支持的,因?yàn)樗茈y理解,又很難被好好使用。
多態(tài)
多態(tài)(Polymorphism)是指由繼承而產(chǎn)生的相關(guān)的不同的類,其對象對同一消息會做出不同的響應(yīng) 。例如,狗和雞都有“叫()”這一方法,但是調(diào)用狗的“叫()”,狗會吠叫;調(diào)用雞的“叫()”,雞則會啼叫。 我們將它體現(xiàn)在偽代碼上:
這樣,雖然同樣是做出 叫 這一種行為,但萊絲和魯斯特具體做出的表現(xiàn)方式將大不相同。多態(tài)性的概念可以用在運(yùn)算符重載上,本文不再贅述。
抽象性
抽象(Abstraction)是簡化復(fù)雜的現(xiàn)實(shí)問題的途徑,它可以為具體問題找到最恰當(dāng)?shù)念惗x,并且可以在最恰當(dāng)?shù)睦^承級別解釋問題。舉例說明,萊絲在大多數(shù)時(shí)候都被當(dāng)作一條狗,但是如果想要讓它做牧羊犬做的事,你完全可以調(diào)用牧羊犬的方法。如果狗這個(gè)類還有動物的父類,那么你完全可以視萊絲為一個(gè)動物。
歷史
面向?qū)ο蟪绦蛟O(shè)計(jì)的雛形,早在1960年的Simula語言中即可發(fā)現(xiàn),當(dāng)時(shí)的程序設(shè)計(jì)領(lǐng)域正面臨著一種危機(jī):在軟硬件環(huán)境逐漸復(fù)雜的情況下,軟件如何得到良好的維護(hù)?面向?qū)ο蟪绦蛟O(shè)計(jì)在某種程度上通過強(qiáng)調(diào)可重復(fù)性解決了這一問題。20世紀(jì)70年代的Smalltalk語言在面向?qū)ο蠓矫婵胺Q經(jīng)典——以至于30年后的今天依然將這一語言視為面向?qū)ο笳Z言的基礎(chǔ)。
計(jì)算機(jī)科學(xué)中對象和實(shí)例概念的最早萌芽可以追溯到麻省理工學(xué)院的PDP-1系統(tǒng)。這一系統(tǒng)大概是最早的基于容量架構(gòu)(capability based architecture)的實(shí)際系統(tǒng)。另外1963年Ivan Sutherland的Sketchpad應(yīng)用中也蘊(yùn)含了同樣的思想。對象作為編程實(shí)體最早是于1960年代由Simula 67語言引入思維。Simula這一語言是奧利-約翰·達(dá)爾和克利斯登·奈加特在挪威奧斯陸計(jì)算機(jī)中心為模擬環(huán)境而設(shè)計(jì)的。(據(jù)說,他們是為了模擬船只而設(shè)計(jì)的這種語言,并且對不同船只間屬性的相互影響感興趣。他們將不同的船只歸納為不同的類,而每一個(gè)對象,基于它的類,可以定義它自己的屬性和行為。)這種辦法是分析式程序的最早概念體現(xiàn)。在分析式程序中,我們將真實(shí)世界的對象映射到抽象的對象,這叫做“模擬”。Simula不僅引入了“類”的概念,還應(yīng)用了實(shí)例這一思想——這可能是這些概念的最早應(yīng)用。
20世紀(jì)70年代施樂PARC研究所發(fā)明的Smalltalk語言將面向?qū)ο蟪绦蛟O(shè)計(jì)的概念定義為,在基礎(chǔ)運(yùn)算中,對對象和消息的廣泛應(yīng)用。Smalltalk的創(chuàng)建者深受Simula 67的主要思想影響,但Smalltalk中的對象是完全動態(tài)的——它們可以被創(chuàng)建、修改并銷毀,這與Simula中的靜態(tài)對象有所區(qū)別。此外,Smalltalk還引入了繼承性的思想,它因此一舉超越了不可創(chuàng)建實(shí)例的程序設(shè)計(jì)模型和不具備繼承性的Simula。此外,Simula 67的思想亦被應(yīng)用在許多不同的語言,如Lisp、Pascal。
面向?qū)ο蟪绦蛟O(shè)計(jì)在80年代成為了一種主導(dǎo)思想,這主要應(yīng)歸功于C++——C語言的擴(kuò)充版。在圖形用戶界面(GUI)日漸崛起的情況下,面向?qū)ο蟪绦蛟O(shè)計(jì)很好地適應(yīng)了潮流。GUI和面向?qū)ο蟪绦蛟O(shè)計(jì)的緊密關(guān)聯(lián)在Mac OS X中可見一斑。Mac OS X是由Objective-C語言寫成的,這一語言是一個(gè)仿Smalltalk的C語言擴(kuò)充版。面向?qū)ο蟪绦蛟O(shè)計(jì)的思想也使事件處理式的程序設(shè)計(jì)更加廣泛被應(yīng)用(雖然這一概念并非僅存在于面向?qū)ο蟪绦蛟O(shè)計(jì))。一種說法是,GUI的引入極大地推動了面向?qū)ο蟪绦蛟O(shè)計(jì)的發(fā)展。
蘇黎世聯(lián)邦理工學(xué)院的尼克勞斯·維爾特和他的同事們對抽象數(shù)據(jù)和模塊化程序設(shè)計(jì)進(jìn)行了研究。Modula-2將這些都包括了進(jìn)去,而Oberon則包括了一種特殊的面向?qū)ο蠓椒ā煌赟malltalk與C++。
面向?qū)ο蟮奶匦砸脖患尤肓水?dāng)時(shí)較為流行的語言:Ada、BASIC、Lisp、Fortran、Pascal以及種種。由于這些語言最初并沒有面向?qū)ο蟮脑O(shè)計(jì),故而這種糅合常常會導(dǎo)致兼容性和維護(hù)性的問題。與之相反的是,“純正的”面向?qū)ο笳Z言卻缺乏一些程序員們賴以生存的特性。在這一大環(huán)境下,開發(fā)新的語言成為了當(dāng)務(wù)之急。作為先行者,Eiffel成功地解決了這些問題,并成為了當(dāng)時(shí)較受歡迎的語言。
在過去的幾年中,Java語言成為了廣為應(yīng)用的語言,除了它與C和C++語法上的近似性。Java的可移植性是它的成功中不可磨滅的一步,因?yàn)檫@一特性,已吸引了龐大的程序員群的投入。
在最近的計(jì)算機(jī)語言發(fā)展中,一些既支持面向?qū)ο蟪绦蛟O(shè)計(jì),又支持面向過程程序設(shè)計(jì)的語言悄然浮出水面。它們中的佼佼者有Python、Ruby等等。
正如面向過程程序設(shè)計(jì)使得結(jié)構(gòu)化程序設(shè)計(jì)的技術(shù)得以提升,現(xiàn)代的面向?qū)ο蟪绦蛟O(shè)計(jì)方法使得對設(shè)計(jì)模式的用途、契約式設(shè)計(jì)和建模語言(如UML)技術(shù)也得到了一定提升。
面向?qū)ο缶幊陶Z言
支持部分或絕大部分面向?qū)ο筇匦缘恼Z言即可稱為基于對象的或面向?qū)ο蟮恼Z言。Simula(1967)被視為第一個(gè)具有面向?qū)ο筇匦缘恼Z言。早期,完全面向?qū)ο蟮恼Z言主要包括Smalltalk等語言,目前較為流行的語言中有Java、C#、Eiffel等。隨著軟件工業(yè)的發(fā)展,比較早的面向過程的語言在近些年的發(fā)展中也紛紛吸收了許多面向?qū)ο蟮母拍?,比如C→C++,C→Objective-C,BASIC→Visual Basic→Visual Basic .NET,Pascal→Object Pascal,Ada→Ada95?!凹兇狻钡拿嫦?qū)ο笳Z言, 因?yàn)樗械臇|西都是由對象所組成,例如: Eiffel, Emerald, JADE, Obix, Ruby, Scala,Smalltalk, Self.
腳本中的OOP
近年來,面向?qū)ο蟮某绦蛟O(shè)計(jì)越來越流行于腳本語言中。Python和Ruby是創(chuàng)建在OOP原理的腳本語言,Perl和PHP亦分別在Perl 5和PHP 4時(shí)加入面向?qū)ο筇匦浴?/span>
參見
一次且僅一次(once and only once,OAOO)
Distributed Component Object Model
UML
延伸閱讀
Abadi, Martin; Luca Cardelli. A Theory of Objects. Springer Verlag. 1998. ISBN 0-387-94775-2.
Abelson, Harold; Gerald Jay Sussman.Structure and Interpretation of Computer Programs. MIT Press. 1997. ISBN 0-262-01153-0.
Armstrong, Deborah J.The Quarks of Object-Oriented Development. Communications of the ACM. February 2006, 49 (2): 123–128 [ 8 August 2006] . ISSN 0001-0782 . doi:10.1145/1113034.1113040 .
Booch, Grady. Object-Oriented Analysis and Design with Applications.Addison-Wesley. 1997. ISBN 0-8053-5340-2.
Eeles, Peter; Oliver Sims. Building Business Objects. John Wiley & Sons. 1998. ISBN 0-471-19176-0.
Gamma, Erich; Richard Helm, Ralph Johnson, John Vlissides. Design Patterns: Elements of Reusable Object Oriented Software. Addison-Wesley. 1995. ISBN 0-201-63361-2.
Harmon, Paul; William Morrissey. The Object Technology Casebook - Lessons from Award-Winning Business Applications. John Wiley & Sons. 1996. ISBN 0-471-14717-6.
Jacobson, Ivar. Object-Oriented Software Engineering: A Use Case-Driven Approach. Addison-Wesley. 1992. ISBN 0-201-54435-0.
Kay, Alan.The Early History of Smalltalk.
Meyer, Bertrand. Object-Oriented Software Construction. Prentice Hall. 1997. ISBN 0-13-629155-4.
Pecinovsky, Rudolf.OOP - Learn Object Oriented Thinking & Programming. Bruckner Publishing. 2013. ISBN 978-80-904661-8-0.
Rumbaugh, James; Michael Blaha; William Premerlani; Frederick Eddy; William Lorensen. Object-Oriented Modeling and Design. Prentice Hall. 1991. ISBN 0-13-629841-9.
Schach, Stephen. Object-Oriented and Classical Software Engineering, Seventh Edition.McGraw-Hill. 2006. ISBN 0-07-319126-4.
Schreiner, Axel-Tobias. Object oriented programming with ANSI-C. Hanser. 1993. ISBN 3-446-17426-5. hdl:1850/8544.
Taylor, David A. Object-Oriented Information Systems - Planning and Implementation. John Wiley & Sons. 1992. ISBN 0-471-54364-0.
Weisfeld, Matt. The Object-Oriented Thought Process, Third Edition.Addison-Wesley. 2009. ISBN 0-672-33016-4.
West, David. Object Thinking (Developer Reference). Microsoft Press. 2004. ISBN 0735619654.
免責(zé)聲明:以上內(nèi)容版權(quán)歸原作者所有,如有侵犯您的原創(chuàng)版權(quán)請告知,我們將盡快刪除相關(guān)內(nèi)容。感謝每一位辛勤著寫的作者,感謝每一位的分享。
- 有價(jià)值
- 一般般
- 沒價(jià)值
{{item.userName}} 舉報(bào)
{{item.time}} {{item.replyListShow ? '收起' : '展開'}}評論 {{curReplyId == item.id ? '取消回復(fù)' : '回復(fù)'}}
{{_reply.userName}} 舉報(bào)
{{_reply.time}}