1. 程式人生 > >深入理解面向過程與面向物件的思想差異與各自特色

深入理解面向過程與面向物件的思想差異與各自特色

一、什麼是面向過程

面向過程是一種思維方式。當試圖通過面向過程解決問題時,我們的關注點在於問題解決的流程,重在這個過程的控制,需要用大量的模組(模組化的思想源自於硬體,在C語言中是函式)將大問題拆解,程式設計師通過控制模組的執行順序以解決問題。

舉個例子,當我們解決一個“如何將大象裝入冰箱?”的問題時,最簡單的解決思路是面向過程解決:
1、關注過程,將大問題拆解為小問題,實現每個小問題的解決方法
a、開啟冰箱門
b、將大象裝入冰箱
c、關閉冰箱門
2、通過控制程式碼,控制模組執行,執行順序為a->b->c,問題解決。

在日常生活或者說日常程式設計中,簡單的問題用面向過程的思路解決,更加直接有效,但是當問題的規模稍大時,如要描述三萬個人吃飯的問題,或者要構建一個航空母艦模型的時候,用面向過程的思想是遠遠不夠的。而且面向過程程式的程式碼複用性、可擴充套件性、可移植性、靈活性、健壯性都會在處理大規模問題中出現問題。

二、什麼是物件?什麼是面向物件的思想?有什麼好處?

1、物件與類

萬事萬物都是物件,物件是自然界的任一個體,比如一本書、一支筆,一片葉子等,而物件和物件間是有相似之處的,比如書(每本書都是一個物件)都是由紙做成的,都印著內容(性質上的相似點),都是用來看的(行為上的相似點),將這些相似之處抽象出來就是類(抽象這個詞很難懂,那麼說成是分類、提取出事物的共同要素更易理解),類的例項就是物件。

2、面向物件思想

面向物件最基本的要素就是抽象,比如剛剛提到的描述三萬人吃飯的問題,首先要解決的是三萬個人描述的問題,三萬個人都是人,有鼻子有眼,都要吃飯,那我們把“人”抽象出來,他們的共性就提取出來了,描述起來就容易太多了。每個人的差異交給繼承多型去做吧。而吃飯的過程就很簡單了,用面向過程的思想解決就好了,所以面向物件是建立在面向過程基礎上解決問題的,面向物件更適合解決較複雜的問題。

剛剛提到的構建航空母艦模型的問題,面向過程肯定是不行的。而用面向物件也有一定問題,因為一個航空母艦是由太多太多元件構成的,每個元件都是一個物件的話,那麼程式需要控制太多物件,而物件和物件的依賴關係也極其複雜,再通過程式控制物件的生命週期就不現實了。這時我們就想如果有一個靠譜的第三方為為我們管理物件就好了,這就出現了大名鼎鼎的spring了,它通過將物件的依賴關係存入xml中,在我們需要某個物件的時候,spring容器為我們建立,並將物件間的依賴關係注入(依賴注入)。物件的控制權由程式轉向了spring容器,也就是IOC(控制反轉)。

3、面向物件的特性除了抽象,還有封裝、繼承、多型等特性

封裝是一種把程式碼和程式碼所操作的資料捆綁在一起,使這兩者不受外界干擾和誤用的機制。封裝可被理解為一種用做保護的包裝器,以防止程式碼和資料被包裝器外部所定義的其他程式碼任意訪問。對包裝器內部程式碼與資料的訪問通過一個明確定義的介面來控制。封裝程式碼的好處是每個人都知道怎樣訪問程式碼,進而無需考慮實現細節就能直接使用它,同時不用擔心不可預料的副作用。

在JAVA中,最基本的封裝單元是類,一個類定義著將由一組物件所共享的行為(資料和程式碼)。一個類的每個物件均包含它所定義的結構與行為,這些物件就好象是一個模子鑄造出來的.所以物件也叫做類的例項.

在定義一個類時,需要指定構成該類的程式碼與資料。特別是,類所定義的物件叫做成員變數或例項變數,操作資料的程式碼叫做成員方法。方法定義怎樣使用成員變數,這意味著類的行為和介面要由操作例項資料的方法來定義.。

由於類的用途是封裝複雜性,所以類的內部有隱藏實現複雜性的機制。所以JAVA中提供了私有和公有的訪問模式,類的公有介面代表外部的使用者應該知道或可以知道的每件東西。私有的方法資料只能通過該類的成員程式碼來訪問。這就可以確保不會發生不希望的事情.。

4.繼承

繼承是指一個物件從另一個物件中獲得屬性的過程。是面向物件程式設計的三大原則之二,它支援按層次分類的概念。例如,波斯貓是貓的一種,貓又是哺乳動物的一種,哺乳動物又是動物的一種。如果不使用層次的概念,每個物件需要明確定義各自的全部特徵。通過層次分類方式,一個物件只需要在它的類中定義是它成為唯一的 各個屬性,然後從父類中繼承它的通用屬性。因此,正是由於繼承機制,才使得一個物件可以成為一個通用類的一個特定例項。一個深度繼承的子類將繼承它在類層次中的每個祖先的所有屬性,增強了程式碼的可重用行。而且子類可以通過重寫父類方法或者定義自身的方法,使其擁有自身的特色,使程式的可擴充套件性大大提升

繼承與封裝可以互相作用。如果一個給定的類封裝了某些屬性,它的任何子類將會含有同樣得屬性,另加各個子類所有得屬性.這是面向物件程式在複雜性上呈線性而非幾何增長的一個重要概念。新的子類繼承其所有祖先的所有屬性。子類和系統中的其他程式碼不會產生無法預料的互動作用.

5.多型

多型是指一個方法只能有一個名稱,但可以有許多形態,也就是程式中可以定義多個同名的方法,用”一個介面,多個方法”來描述。可以通過方法的引數和型別引用.。
執行時多型是指:在程式執行過程中才決定用哪個方法,多型性是允許你將父類物件設定成和它的一個或多個子物件相等的技術,賦值後,父物件就可以根據當前賦值給它的子物件的特性運作。

6.封裝,繼承,多型的組合使用 (總結)

在由封裝,繼承,多型所組成的環境中,程式設計師可以編寫出比面向過程模型更方便、健壯,更具擴充套件性的程式。

封裝:對於介面使用者,封裝可以封裝複雜性,使用者不必知道實現細節即可使用;對於程式設計師,通過封裝可以防止程式碼和資料被外部所定義的其他程式碼任意訪問,增強了程式碼的健壯性;並且不必修改公有介面的程式碼即可實現程式的移植。

繼承:經過仔細設計的類層次結構是程式碼重用與擴充套件的基礎。

多型:能使程式設計師開發出簡潔,易懂,易修改,更靈活的程式碼。

例如:汽車 從繼承的角度看,駕駛員都依靠繼承性來駕駛不同型別(子類)的汽車,無論這輛車是轎車還是卡車,是賓士牌還是菲亞特牌,駕駛員都能找到方向盤,手剎,換檔器。經過一段時間駕駛後,都能知道手動檔與自動檔之間的差別,因為他們實際上都知道這兩者的共同超類:傳動裝置.。

從封裝的角度看,駕駛員總是看到封裝好的特性。剎車隱藏了許多複雜性,其外觀如此簡單,用腳就能操作它。發動機,手剎,輪胎大小的實現對與剎車類的定義沒有影響.。

從多型的角度看,剎車系統有正鎖反鎖之分,駕駛員只用腳踩剎車停車,同樣的介面可以用來控制若干種不同的實現(正鎖或反鎖).

這樣各個獨立的構件才被轉換為汽車這個物件的。同樣,通過使用面向物件的設計原則,程式設計師可以把一個複雜程式的各個構件組合在一起,形成一個一致,健壯,可維護的程式。

參考:
1、《Java程式設計思想》第一章物件導論
2、 百度百科與百度知道熱心網友
3、 尚學堂博文