1.什么是面向?qū)ο?/h3>
面向?qū)ο箝_發(fā)方法(ObjectOriented,OO)又稱:快速原型法。
客觀世界是由各種各樣的對象組成的,每種對象都有各自的內(nèi)部狀態(tài)和運(yùn)動規(guī)律,不同對象之間的相互作用和聯(lián)系就構(gòu)成了各種不同的系統(tǒng)往声。
在設(shè)計(jì)和實(shí)現(xiàn)一個(gè)客觀系統(tǒng)時(shí),在滿足需求的條件下戳吝,把系統(tǒng)設(shè)計(jì)成一些不可變的(相對固定)部分組成的最小集合(最好的設(shè)計(jì))浩销。這些不可變的部分就是所謂的對象。
2.面向?qū)ο箝_發(fā)方法的組成
面向?qū)ο箝_發(fā)方法(ObjectOriented,OO)又稱:快速原型法。
客觀世界是由各種各樣的對象組成的,每種對象都有各自的內(nèi)部狀態(tài)和運(yùn)動規(guī)律,不同對象之間的相互作用和聯(lián)系就構(gòu)成了各種不同的系統(tǒng)往声。
在設(shè)計(jì)和實(shí)現(xiàn)一個(gè)客觀系統(tǒng)時(shí),在滿足需求的條件下戳吝,把系統(tǒng)設(shè)計(jì)成一些不可變的(相對固定)部分組成的最小集合(最好的設(shè)計(jì))浩销。這些不可變的部分就是所謂的對象。
1听哭、面向?qū)ο蟮模ㄐ枨螅┓治鯫OA
2慢洋、面向?qū)ο蟮脑O(shè)計(jì)OOD
3、面向?qū)ο蟮某绦騉OP
3.面向?qū)ο箝_發(fā)方法的開發(fā)過程
1陆盘、系統(tǒng)調(diào)查和需求分析:對系統(tǒng)將要面臨的具體管理問題以及用戶對系統(tǒng)開發(fā)的需求進(jìn)行調(diào)查研究普筹,即先弄清要干什么的問題。
2隘马、分析問題的性質(zhì)和求解問題:在繁雜的問題域中抽象地識別出對象以及其行為太防、結(jié)構(gòu)、屬性酸员、方法等蜒车。一般稱之為面向?qū)ο蟮姆治觯碠OA幔嗦。
3酿愧、整理問題:對分析的結(jié)果作進(jìn)一步的抽象、歸類邀泉、整理嬉挡,并最終以范式的形式將它們確定下來叛氨。一般稱之為面向?qū)ο蟮脑O(shè)計(jì),即OOD棘伴。
4、程序?qū)崿F(xiàn):用面向?qū)ο蟮?a target="_blank" rel="nofollow">程序設(shè)計(jì)語言將上一步整理的范式直接映射(即直接用程序設(shè)計(jì)語言來取代)為應(yīng)用軟件屁置。一般稱之為面向?qū)ο蟮某绦蚝缚洌碠OP。
5蓝角、識別客觀世界中的對象以及行為阱穗,分別獨(dú)立設(shè)計(jì)出各個(gè)對象的實(shí)體;分析對象之間的聯(lián)系和相互所傳遞的信息使鹅,由此構(gòu)成信息系統(tǒng)的模型揪阶;由信息系統(tǒng)模型轉(zhuǎn)換成軟件系統(tǒng)的模型,對各個(gè)對象進(jìn)行歸并和整理患朱,并確定它們之間的聯(lián)系鲁僚;由軟件系統(tǒng)模型轉(zhuǎn)換成目標(biāo)系統(tǒng)。
4.面向?qū)ο蟮幕靖拍?/h3>
- 對象
對象是要研究的任何事物裁厅。從一本書到一家圖書館冰沙,單的整數(shù)到整數(shù)列龐大的數(shù)據(jù)庫、極其復(fù)雜的自動化工廠执虹、航天飛機(jī)都可看作對象拓挥,它不僅能表示有形的實(shí)體,也能表示無形的(抽象的)規(guī)則袋励、計(jì)劃或事件侥啤。對象由數(shù)據(jù)(描述事物的屬性)和作用于數(shù)據(jù)的操作(體現(xiàn)事物的行為)構(gòu)成一獨(dú)立整體。從程序設(shè)計(jì)者來看茬故,對象是一個(gè)程序模塊盖灸,從用戶來看,對象為他們提供所希望的行為均牢。在對內(nèi)的操作通常稱為方法糠雨。一個(gè)對象請求另一對象為其服務(wù)的方式是通過發(fā)送消息。
- 類
類是對象的模板徘跪。即類是對一組有相同數(shù)據(jù)和相同操作的對象的定義甘邀,一個(gè)類所包含的方法和數(shù)據(jù)描述一組對象的共同行為和屬性。類是在對象之上的抽象垮庐,對象則是類的具體化松邪,是類的實(shí)例。類可有其子類哨查,也可有其它類逗抑,形成類層次結(jié)構(gòu)。
- 消息
消息是對象之間進(jìn)行通信的一種規(guī)格說明。一般它由三部分組成:接收消息的對象邮府、消息名及實(shí)際變元荧关。
- 繼承
繼承性(Inheritance)是指,在某種情況下褂傀,一個(gè)類會有“子類”忍啤。子類比原本的類(稱為父類)要更加具體化。例如仙辟,“狗”這個(gè)類可能會有它的子類“牧羊犬”和“吉娃娃犬”同波。在這種情況下,“萊絲”可能就是牧羊犬的一個(gè)實(shí)例叠国。子類會繼承父類的屬性和行為未檩,并且也可包含它們自己的。我們假設(shè)“狗”這個(gè)類有一個(gè)方法(行為)叫做“吠叫()”和一個(gè)屬性叫做“毛皮顏色”粟焊。它的子類(前例中的牧羊犬和吉娃娃犬)會繼承這些成員冤狡。這意味著程序員只需要將相同的代碼寫一次。
在偽代碼中我們可以這樣寫:
類牧羊犬:繼承狗定義萊絲是牧羊犬萊絲.吠叫() /* 注意這里調(diào)用的是狗這個(gè)類的吠叫方法吆玖。/
回到前面的例子筒溃,“牧羊犬”這個(gè)類可以繼承“毛皮顏色”這個(gè)屬性,并指定其為棕白色沾乘。而“吉娃娃犬”則可以繼承“吠叫()”這個(gè)方法怜奖,并指定它的音調(diào)高于平常。子類也可以加入新的成員翅阵,例如歪玲,“吉娃娃犬”這個(gè)類可以加入一個(gè)方法叫做“顫抖()”。設(shè)若用“牧羊犬”這個(gè)類定義了一個(gè)實(shí)例“萊絲”掷匠,那么萊絲就不會顫抖滥崩,因?yàn)檫@個(gè)方法是屬于吉娃娃犬的,而非牧羊犬讹语。事實(shí)上钙皮,我們可以把繼承理解為“是”或“屬于”。萊絲“是”牧羊犬顽决,牧羊犬“屬于”狗類短条。因此,萊絲既得到了牧羊犬的屬性才菠,又繼承了狗的屬性茸时。 我們來看偽代碼:
類吉娃娃犬:繼承狗開始 公有成員: 顫抖()結(jié)束類牧羊犬:繼承狗定義萊絲是牧羊犬萊絲.顫抖() / 錯(cuò)誤:顫抖是吉娃娃犬的成員方法。 */
當(dāng)一個(gè)類從多個(gè)父類繼承時(shí)赋访,我們稱之為“多重繼承”可都。如一只狗既是吉娃娃犬又是牧羊犬(雖然事實(shí)上并不合邏輯)缓待。多重繼承并不總是被支持的,因?yàn)樗茈y理解渠牲,又很難被好好使用旋炒。
- 封裝性
具備封裝性(Encapsulation)的面向?qū)ο蟪绦蛟O(shè)計(jì)隱藏了某一方法的具體執(zhí)行步驟,取而代之的是通過消息傳遞機(jī)制傳送消息給它签杈。因此国葬,舉例來說,“狗”這個(gè)類有“吠叫()”的方法芹壕,這一方法定義了狗具體該通過什么方法吠叫。但是接奈,萊絲的朋友并不知道它到底是如何吠叫的踢涌。
從實(shí)例來看:
/* 一個(gè)面向過程的程序會這樣寫: /定義萊絲萊絲.設(shè)置音調(diào)(5)萊絲.吸氣()萊絲.吐氣()/ 而當(dāng)狗的吠叫被封裝到類中,任何人都可以簡單地使用: */定義萊絲是狗萊絲.吠叫()
封裝是通過限制只有特定類的對象可以訪問這一特定類的成員序宦,而它們通常利用接口實(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è)類可以訪問所有成員腌巾。[1]
- 多態(tài)
多態(tài)(Polymorphism)是指由繼承而產(chǎn)生的相關(guān)的不同的類遂填,其對象對同一消息會做出不同的響應(yīng)。例如澈蝙,狗和雞都有“叫()”這一方法吓坚,但是調(diào)用狗的“叫()”,狗會吠叫灯荧;調(diào)用雞的“叫()”礁击,雞則會啼叫。
結(jié)束定義萊絲是狗定義魯斯特是雞萊絲.叫()魯斯特.叫()
這樣逗载,雖然同樣是做出叫這一種行為哆窿,但萊絲和魯斯特具體做出的表現(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è)動物誉己。
5.面向?qū)ο箝_發(fā)的特征
封裝性眉尸。面向?qū)ο蠓椒ㄖ校绦蚝蛿?shù)據(jù)是封裝在一起的巨双,對象作為一個(gè)實(shí)體噪猾,其操作隱藏在方法中,其狀態(tài)由對象的"屬性"來描述筑累,并且只能通過對象中的"方法"來改變袱蜡,從外界無從得知。封裝性構(gòu)成了面向?qū)ο蠓椒ǖ幕A(chǔ)慢宗。因而坪蚁,這種方法的創(chuàng)始人Codd和YOuMn認(rèn)為,面向?qū)ο缶褪?對象+屬性+方法"镜沽。
抽象性敏晤。面向?qū)ο蠓椒ㄖ校褟木哂泄餐再|(zhì)的實(shí)體中抽象出的事物本質(zhì)特征概念缅茉,稱為"類"(Class)嘴脾,對象是類的一個(gè)實(shí)例。類中封裝了對象共有的屬性和方法蔬墩,通過實(shí)例化一個(gè)類創(chuàng)建的對象统阿,自動具有類中規(guī)定的屬性和方法。
繼承性筹我。繼承性是類特有的性質(zhì)扶平,類可以派生出子類,子類自動繼承父類的屬性與方法蔬蕊。這樣结澄,在定義子類時(shí),只須說明它不同于父類的特性岸夯,從而可大大提高軟件的可重用性麻献。
多態(tài)。所謂多態(tài)就是指一個(gè)類實(shí)例的相同方法在不同情形有不同表現(xiàn)形式猜扮。多態(tài)機(jī)制使具有不同內(nèi)部結(jié)構(gòu)的對象可以共享相同的外部接口勉吻。這意味著,雖然針對不同對象的具體操作不同旅赢,但通過一個(gè)公共的類齿桃,它們(那些操作)可以通過相同的方式予以調(diào)用惑惶。
6.面向?qū)ο蟮奈宕蠡驹瓌t
單一職責(zé)原則SRP(Single Responsibility Principle)
是指一個(gè)類的功能要單一,不能包羅萬象短纵。如同一個(gè)人一樣带污,分配的工作不能太多,否則一天到晚雖然忙忙碌碌的香到,但效率卻高不起來鱼冀。開放封閉原則OCP(Open-Close Principle)
一個(gè)模塊在擴(kuò)展性方面應(yīng)該是開放的而在更改性方面應(yīng)該是封閉的。比如:一個(gè)網(wǎng)絡(luò)模塊悠就,原來只服務(wù)端功能千绪,而現(xiàn)在要加入客戶端功能,
那么應(yīng)當(dāng)在不用修改服務(wù)端功能代碼的前提下梗脾,就能夠增加客戶端功能的實(shí)現(xiàn)代碼翘紊,這要求在設(shè)計(jì)之初,就應(yīng)當(dāng)將服務(wù)端和客戶端分開藐唠,公共部分抽象出來。替換原則(the Liskov Substitution Principle LSP)
子類應(yīng)當(dāng)可以替換父類并出現(xiàn)在父類能夠出現(xiàn)的任何地方鹉究。比如:公司搞年度晚會宇立,所有員工可以參加抽獎,那么不管是老員工還是新員工自赔,
也不管是總部員工還是外派員工妈嘹,都應(yīng)當(dāng)可以參加抽獎,否則這公司就不和諧了绍妨。依賴原則(the Dependency Inversion Principle DIP) 具體依賴抽象润脸,上層依賴下層。假設(shè)B是較A低的模塊他去,但B需要使用到A的功能毙驯,
這個(gè)時(shí)候,B不應(yīng)當(dāng)直接使用A中的具體類: 而應(yīng)當(dāng)由B定義一抽象接口灾测,并由A來實(shí)現(xiàn)這個(gè)抽象接口爆价,B只使用這個(gè)抽象接口:這樣就達(dá)到
了依賴倒置的目的,B也解除了對A的依賴媳搪,反過來是A依賴于B定義的抽象接口铭段。通過上層模塊難以避免依賴下層模塊,假如B也直接依賴A的實(shí)現(xiàn)秦爆,那么就可能造成循環(huán)依賴序愚。一個(gè)常見的問題就是編譯A模塊時(shí)需要直接包含到B模塊的cpp文件,而編譯B時(shí)同樣要直接包含到A的cpp文件等限。接口分離原則(the Interface Segregation Principle ISP)
模塊間要通過抽象接口隔離開爸吮,而不是通過具體的類強(qiáng)耦合起來
7.為什么需要面向?qū)ο蠓椒?/h3>
(1)面向?qū)ο蟮姆椒ǜ咏谌祟惖淖匀凰季S芬膝。人類在認(rèn)識和理解現(xiàn)實(shí)世界中普遍運(yùn)用的三個(gè)構(gòu)造法則是區(qū)分對象及其屬性、區(qū)分整體對象及其組成部分拗胜、區(qū)分及形成不同對象類蔗候。而面向?qū)ο笳腔趯ο蠹皩傩浴㈩悓偌俺蓡T埂软、整體及其部分這些概念基礎(chǔ)之上的锈遥。因而它必然更容易被理解和運(yùn)用。
(2)系統(tǒng)分析勘畔、系統(tǒng)設(shè)計(jì)及實(shí)現(xiàn)之間采用同樣的角度看待問題甚至同樣的表示方法來描述間題,它們之間的連接是自然的無縫連接所灸。
(3)面向?qū)ο蟮姆椒▽ο蟮膶傩约胺?wù)視為一個(gè)整體。
這更符合客觀世界的規(guī)律,從而使其理解與實(shí)現(xiàn)起來更加容易,進(jìn)一步減少維護(hù)的費(fèi)用炫七。
(4)繼承的方法一方面符合客觀世界的規(guī)律,一方面加強(qiáng)代碼重用的可能性,以便提高軟件的開發(fā)效率爬立。
(5)信息隱蔽原理使系統(tǒng)在變化的環(huán)境中有良好的適應(yīng)性,從而使整個(gè)系統(tǒng)更加穩(wěn)定和易于維護(hù)。
總之,面向?qū)ο蟮姆椒ㄒ环矫娓子谌藗兝斫獠⒂成洮F(xiàn)實(shí)世界,另一方面可以提高軟件開發(fā)效率万哪、可靠性及可維護(hù)性侠驯。
8.面向過程和面向?qū)ο蟮膮^(qū)別
在知乎上看到一個(gè)答案,很精辟
一個(gè)程序要完成一個(gè)任務(wù)就相當(dāng)于講一個(gè)故事奕巍。
面向過程就是編年史
面向?qū)ο缶褪羌o(jì)傳史
對于復(fù)雜的程序/宏大的故事吟策,事實(shí)都證明了 面向?qū)ο?紀(jì)傳是更合理的表述方法。
編年史:按照時(shí)間線索
紀(jì)傳史:按照人物線索