說起面向?qū)ο螅蠹铱赡軙氲狡渌?,但是此對象非彼對象哈哈,不必驚慌,也特別好搞定。
在聽到面向?qū)ο笾按蠹乙惨欢〞佑|學(xué)習(xí)到面向過程相關(guān)的,那么它們兩個之間到底是有什么關(guān)系呢,我先給咱嘮嘮。
面向過程與面向?qū)ο蟮膮^(qū)別
面向過程—步驟化
當(dāng)軟件規(guī)模超過一定的尺度后,采用結(jié)構(gòu)化程序設(shè)計,其開發(fā)和維護就越來越難控制。其根本原因就在于面向過程的結(jié)構(gòu)化程序設(shè)計的方法與現(xiàn)實世界往往都不一致,結(jié)構(gòu)化程序設(shè)計的思想往往很難貫徹到底。
在結(jié)構(gòu)化程序設(shè)計中,采用的是“ 自頂向下,逐步細(xì)化 ”的思想。具體操作方法是模塊化,是按功能來分的,所以也稱功能塊。在C++中稱為一個函數(shù),一個函數(shù)解決一個問題,即實現(xiàn)一個功能或一個操作。
在模塊化的思想中已經(jīng)出現(xiàn)了封裝的概念,這個封裝是把數(shù)據(jù)封裝到模塊中,即局部變量。但這是很不徹底的,因為模塊是功能的抽象,而數(shù)據(jù)則是具有其個性的,一旦發(fā)生哪怕是一點變化,抽象的功能模塊就不再適用了。可維護性差成了制約機構(gòu)化程序設(shè)計應(yīng)用的瓶頸。
總的來說,面向過程就是分析出實現(xiàn)需求所需要的步驟,通過函數(shù)一步一步實現(xiàn)這些步驟,接著依次調(diào)用即可。
面向?qū)ο蟆袨榛?/p>
面向?qū)ο笫前颜麄€需求按照特點、功能劃分,將這些存在共性的部分封裝成類(類實例化后才是對象),創(chuàng)建了對象不是為了完成某一個步驟,而是描述某個事務(wù)在解決問題的步驟中的行為。
對象是面向?qū)ο蠹夹g(shù)的核心所在,面向?qū)ο蠹夹g(shù)中的對象就是現(xiàn)實世界中某個具體的物理實體在計算機邏輯中的映射和體現(xiàn)。
面向過程和面向?qū)ο蟮膬?yōu)缺點及用途
總結(jié):
- 類是一組相關(guān)的 屬性(變量) 和 行為(方法) 的集合。是一個抽象概念設(shè)計的產(chǎn)物。
- 對象是該類事物的具體表現(xiàn)形式。具體存在的實體。
- 成員變量是對象的屬性(可以使變量、指針、數(shù)組等),屬性的值確定對象的狀態(tài)。
- 成員函數(shù)是對象的方法,確定對象的行為。
狀態(tài)和行為是對象的主要屬性
對象的狀態(tài)又稱為對象的靜態(tài)屬性,主要指對象內(nèi)部所包含的各種信息,也就是變量。每個對象個體都有自己專有的內(nèi)部變量,這些變量的值標(biāo)明了對象所處的狀態(tài)。
對象的方法(行為)一方面把對象的內(nèi)部變量包裹,封裝,保護起來,使得只有對象自己的方法才能操作這些內(nèi)部變量,另一方面,對象的方法還是對象與外部環(huán)境和其他對象交互,通信的接口,對象的環(huán)境和其他對象可以通過這個接口來調(diào)用對象的方法,操縱對象的行為和改變對象的狀態(tài)。
對象是現(xiàn)實世界的實體或概念在計算機邏輯中的抽象表示。具體地,對象是具有唯一對象名和固定對外界接口的一組屬性和操作的集合,用來模擬或影響現(xiàn)實世界問題的一個或一組因素。
相對于傳統(tǒng)的面向過程的程序設(shè)計方法,而面向?qū)ο蟮某绦蛟O(shè)計具有的優(yōu)點
對象的數(shù)據(jù)封裝特性徹底消除了傳統(tǒng)結(jié)構(gòu)方法中數(shù)據(jù)與操作分離所帶來的種種問題,提高了程序的可復(fù)性和可維護性,降低了程序員保持?jǐn)?shù)據(jù)與操作相容的負(fù)擔(dān)。
對象的數(shù)據(jù)封裝特性還可以把對象的私有數(shù)據(jù)和公共數(shù)據(jù)分離開,保護了私有數(shù)據(jù),減少了可能的模塊間干擾,達(dá)到降低程序復(fù)雜性,提高可控性的目的。
對象作為獨立的整體具有良好的自恰性,即它可以通過自身定義的操作來管理自己。一個對象的操作可以完成兩類功能,一是修改自身的狀態(tài),二是向外界發(fā)布消息。
在具有自恰性的同時,對象通過一定的接口和相應(yīng)的消息機制與外界聯(lián)系。這個特性與對象的封裝性結(jié)合在一起,較好地實現(xiàn)了信息的隱藏。
通過繼承可以很方便地實現(xiàn)應(yīng)用的擴展和已有代碼的重復(fù)使用。
總結(jié):
面向?qū)ο蟪绦蛟O(shè)計是將數(shù)據(jù)及數(shù)據(jù)的操作封裝在一起,成為一個不可分割的整體,同時將具有相同特性的實體抽象成為一種新的數(shù)據(jù)類型—類。通過對象間的消息傳遞是整個系統(tǒng)運轉(zhuǎn)。
類和對象關(guān)系和理解
類:一組相關(guān)的屬性和行為的集合,是一個抽象的概念。
對象:該類事務(wù)的具體表現(xiàn)形式,具體存在的個體。
上面這幾個概念,應(yīng)該怎么理解的呢?
類就是對一些具有共性特征,并且行為相似的個體的描述。
比如小楊和小秦都有姓名、年齡、身高、體重等一些屬性,并且兩人都能夠進行聊天、運動等相似的行為。
由于這兩個人具有這些共性的地方,所以我們就把它抽象出來,定義為一個類—人類,而小楊、小秦正是這個類中的個體,而每一個個體才是真正的具體的存在,光提到人類,你只知道應(yīng)該有哪些屬性行為,但你不知道他具體的一些屬性值。比如你知道他屬于“人類”,所以他應(yīng)該擁有姓名,年齡等屬性,但你并不知道他具體叫什么,年齡多大了。而小楊和小秦這兩個具體的對象,卻能夠?qū)崒嵲谠诘闹佬罱衲?3歲了,體重80kg等值。
總結(jié):
類是對象的抽象,而對象是類的具體實例。類是抽象的,不占用內(nèi)存,而根據(jù)類實例化具體的對象,就需要占用內(nèi)存空間了。
面向?qū)ο蟮娜笾饕卣?/strong>
封裝
常見的兩層含義 :一是把對象的屬性和行為看成一個密不可分的整體,將這兩者“封裝”在一個不可分割的獨立單元中;另一個是指“ 信息隱藏 ”,把不需要讓外界知道的信息隱藏起來,有些對象的屬性及行為允許外界用戶知道或使用,但不允許更改,而另一些屬性或行為,則不允許外界知曉,或只允許使用對象的功能,而盡可能隱藏對象的功能實現(xiàn)細(xì)節(jié)。
封裝的好處:
- 可以對成員變量進行更精確的控制。
- 類內(nèi)部的結(jié)構(gòu)可以自由修改。
- 好的封裝能夠減少耦合,符合程序設(shè)計“高內(nèi)聚,低耦合”。
- 隱藏實現(xiàn)細(xì)節(jié)。
- 提供公共的訪問方式。
- 提高代碼的復(fù)用性。
- 提高安全性。
繼承
繼承時面向?qū)ο?a target="_blank">編程技術(shù)的一塊基石,因為它允許創(chuàng)建分等級層次的類。
繼承就是在一個已有類的基礎(chǔ)上派生出新類(例如動物類可以派生出狗類和貓類),子類繼承父類的特征和行為,使得子類對象(實例)具有父類的實例域和方法,或子類從父類繼承方法,使得子類具有父類相同的行為。
繼承的好處:
- 提高代碼的維護性。
- 提高類代碼的復(fù)用性。
- 使得類和類產(chǎn)生了關(guān)系,是多態(tài)的前提(是繼承的一個弊端,讓類的耦合性增強了)。
**繼承概念的實現(xiàn)方式有三類:實現(xiàn)繼承、接口繼承、可視繼承
**
實現(xiàn)繼承:使用基類的屬性和方法而無序額外編碼的能力。
接口繼承:僅使用屬性和方法的名稱,但是子類必須提供實現(xiàn)的能力。
可視繼承:子窗體使用基窗體的外觀和實現(xiàn)代碼的能力。
繼承的特點:
- 子類擁有父類非private的屬性,方法。
- 子類可以擁有自己的屬性和方法,即子類可以對父類進行擴展。
- 子類可以用自己的方式實現(xiàn)父類的方法,即重寫父類方法。
- 提高了類之間的耦合性。
訪問權(quán)限修飾符public、 protected 、private:
多態(tài)
多態(tài)是同一個行為具有多個不同表現(xiàn)形式或形態(tài)的能力,例如:黑白打印機和彩色打印機相同的打印行為卻有著不同的打印效果。
- 對象類型和引用類型之間存在著繼承(類)/ 實現(xiàn)(接口)的關(guān)系。
- 當(dāng)使用多態(tài)方式調(diào)用方法時,首先檢查父類中是否有該方法,如果沒有,則編譯錯誤;如果有,再去調(diào)用子類的同名方法。
- 如果子類重寫了父類的方法,最終執(zhí)行的是子類覆蓋的方法,如果沒有則執(zhí)行的是父類的方法。
多態(tài)的實現(xiàn): 靜態(tài)多態(tài)和動態(tài)多態(tài)
靜態(tài)多態(tài):通過函數(shù)重載和模板來實現(xiàn),是在編譯期間確定,也稱早起綁定。
動態(tài)多態(tài):通過虛函數(shù)和繼承來實現(xiàn),是在運行期確定,也稱晚期綁定(動態(tài)綁定)。
動態(tài)多態(tài)的實現(xiàn):
當(dāng)編譯器發(fā)現(xiàn)類中有虛函數(shù)時,會創(chuàng)建一張?zhí)摵瘮?shù)表,把虛函數(shù)的函數(shù)入口地址放到虛函數(shù)表中,并且在對象中增加一個指針vptr,用于指向類的虛函數(shù)表。當(dāng)派生類覆蓋基類的虛函數(shù)時,會將虛函數(shù)表中對應(yīng)的指針進行替換,從而調(diào)用派生類中覆蓋后的虛函數(shù),從而實現(xiàn)動態(tài)綁定。
虛表:虛表中放置的是虛函數(shù)的入口地址,如果能拿到虛表中的內(nèi)容,即拿到了虛函數(shù)的入口地址,則可以將該函數(shù)調(diào)用起來。
基類虛表構(gòu)建過程 :編譯期間在編譯期間,按照虛函數(shù)在類中聲明的先后次序依次添加到虛表中。
派生類虛表的構(gòu)建過程 :
- 將基類虛表中內(nèi)容拷貝一份放置到子類虛表中。
- 如果子類重寫了基類的某個虛函數(shù),則使用子類自己的虛函數(shù)替換相同偏移量位置的基類虛函數(shù)地址。
- 對于子類新增的虛函數(shù),按照在類中聲明次序,依次放在虛表的后面。
函數(shù)重載、重寫、同名隱藏的對比:
函數(shù)重載:兩個或多個函數(shù)在同一作用域,函數(shù)名相同、參數(shù)列表不同。
重寫:兩個函數(shù)分別在基類和派生類的作用域中,函數(shù)名、參數(shù)、返回值類型都必須相同,基類虛函數(shù)必須為虛函數(shù),派生類函數(shù)最好也為虛函數(shù)。
同名隱藏:兩個函數(shù)分別在基類和派生類的作用域中,函數(shù)名相同,基類和派生類同名函數(shù)不是重寫就是同名隱藏。
多態(tài)的優(yōu)點:
消除類型之間的耦合關(guān)系、可替換性、可擴充性、接口性、靈活性、簡化性。
動態(tài)多態(tài)的作用:
- 隱藏實現(xiàn)細(xì)節(jié),使代碼模塊化,提高代碼的可復(fù)用性。
- 接口重用,使派生類的功能可以被基類的指針/引用所調(diào)用,即向后兼容,提高代碼的可擴充性和可維護性。
動態(tài)多態(tài)的必****要條件:繼承、虛函數(shù)覆蓋、基類指針/引用指向子類對象。
總之,C++多態(tài)的核心,就是用一個更通用的基類指針指向不同的子類實例,為了能調(diào)用正確的方法,我們需要用到虛函數(shù)和虛繼承。在內(nèi)存中,通過虛函數(shù)表來實現(xiàn)子類方法的正確調(diào)用;通過虛基類指針,僅保留一份基類的內(nèi)存結(jié)構(gòu),避免沖突。
面向?qū)ο蟮奈宕笤瓌t
** 單一職責(zé)原則SRP** (Single Responsibility Principle):是指 一個類的功能要單一,不能包羅萬象 。如同一個人一樣,分配的工作不能太多,否則一天到晚雖然忙忙碌碌的,但效率卻高不起來。
**開放封閉原則OCP** (Open-Close Principle):一 個模塊在擴展性方面應(yīng)該是開放的而在更改性方面應(yīng)該是封閉的 。比如:一個網(wǎng)絡(luò)模塊,原來只服務(wù)端功能,而現(xiàn)在要加入客戶端功能,那么應(yīng)當(dāng)在不用修改服務(wù)端功能代碼的前提下,就能夠增加客戶端功能的實現(xiàn)代碼,這要求在設(shè)計之初,就應(yīng)當(dāng)將服務(wù)端和客戶端分開,公共部分抽象出來。
** 里式替換原則LSP** (the Liskov Substitution Principle LSP): 子類應(yīng)當(dāng)可以替換父類并出現(xiàn)在父類能夠出現(xiàn)的任何地方 。比如:公司搞年度晚會,所有員工可以參加抽獎,那么不管是老員工還是新員工,也不管是總部員工還是外派員工,都應(yīng)當(dāng)可以參加抽獎,否則這公司就不和諧了。
**依賴倒置原則DIP** (the Dependency Inversion Principle DIP): 高層模塊(穩(wěn)定)不應(yīng)該依賴低層模塊(變換)都應(yīng)該依賴于抽象(穩(wěn)定)。 抽象(穩(wěn)定)不應(yīng)該依賴于實現(xiàn)細(xì)節(jié)(變化),實現(xiàn)細(xì)節(jié)(變化)應(yīng)該依賴于抽象(穩(wěn)定) 。假設(shè)B是較A低的模塊,但B需要使用到A的功能,這個時候,B不應(yīng)當(dāng)直接使用A中的具體類:而應(yīng)當(dāng)由B定義一抽象接口,并由A來實現(xiàn)這個抽象接口,B只使用這個抽象接口:這樣就達(dá)到了依賴倒置的目的,B也解除了對A的依賴,反過來是A依賴于B定義的抽象接口。通過上層模塊難以避免依賴下層模塊,假如B也直接依賴A的實現(xiàn),那么就可能 造成循環(huán)依賴。一個常見的問題就是編譯A模塊時需要直接包含到B模塊的cpp文件,而編譯B時同樣要直接包含到A的cpp文件。
**接口分離原則ISP** (the Interface Segregation Principle ISP): 模塊間要通過抽象接口隔離開 ,而不是通過具體的類強耦合起來。
-
編程
+關(guān)注
關(guān)注
88文章
3687瀏覽量
95072 -
面向?qū)ο?/span>
+關(guān)注
關(guān)注
0文章
64瀏覽量
10115 -
面向過程
+關(guān)注
關(guān)注
0文章
2瀏覽量
5877
發(fā)布評論請先 登錄
labview面向對象編程
LabVIEW面向對象的ActorFramework(1)
LabVIEW面向對象的ActorFramework(2)
你真的知道面向過程和面向對象的區(qū)別嗎?精選資料分享
談?wù)?b class='flag-5'>面向對象編程
面向對象編程語言的特點
什么是向對象?什么叫面向過程
Java面向對象程序設(shè)計教程

史上最全Python面向對象編程的資料合集
面向過程和面向對象有什么區(qū)別

評論