程序導向程式設計與物件導向程式設計體現了程式設計者的兩種不同的思維方式,本節教學主要介紹程序導向程式設計與物件導向程式設計的區別和聯絡。
程序導向是一種以過程為中心的程式設計思想,它首先分析出解決問題所需要的步驟,然後用函數把這些步驟一步一步實現,在使用時依次呼叫,是一種基礎的順序的思維方式。程序導向開發方式是對計算機底層結構的一層抽象,它將程式分為資料和操縱資料的操作兩部分,其核心問題是資料結構和演算法的開發和優化。常見的支援程序導向的程式語言有 C語言、COBOL 語言等。
物件導向是按人們認識客觀世界的系統思維方式,採用基於物件(實體)的概念建立模型,模擬客觀世界分析、設計、實現軟體的程式設計思想,通過物件導向的理念使計算機軟體系統能與現實世界中的系統一一對應。
物件導向方法直接把所有事物都當作獨立的物件,處理問題過程中所思考的不再主要是怎樣用資料結構來描述問題,而是直接考慮重現問題中各個物件之間的關係。物件導向方法的基礎實現中也包含程序導向的思想。常見的支援物件導向的程式語言有 C++ 語言、C# 語言、Java 語言等。
具體來說,物件導向與程序導向有以下四個方面的不同:
1) 出發點不同
物件導向使用符合常規思維的方式來處理客觀世界的問題,強調把解決問題領域的“動作”直接對映到物件之間的介面上。而程序導向則強調的是過程的抽象化與模組化,是以過程為中心構造或處理客觀世界問題。
2) 層次邏輯關係不同
物件導向使用計算機邏輯來模擬客觀世界中的物理存在,以物件的集合類作為處理問題的單位,盡可能地使計算機世界向客觀世界靠攏,以使處理問題的方式更清晰直接,物件導向使用類的層次結構來體現類之間的繼承與發展。程序導向處理問題的基本單位是能清晰準確地表達過程的模組,用模組的層次結構概括模組或模組間的關係與功能,把客觀世界的問題抽象成計算機可以處理的過程。
3) 資料處理方式與控制程式方式不同
物件導向將資料與對應的程式碼封裝成一個整體,原則上其他物件不能直接修改其資料,即物件的修改只能由自身的成員函數完成,控制程式方式上是通過“事件驅動”來啟用和執行程式的。而程序導向是直接通過程式來處理資料,處理完畢後即可顯示處理的結果,在控制方式上是按照設計呼叫或返回程式,不能自由導航,各模組之間存在著控制與被控制,調動與被呼叫的關係。
4) 分析設計與編碼轉換方式不同
物件導向貫穿於軟體生命週期的分析、設計及編碼中,是一種平滑的過程,從分析到設計再到編碼是採用一致性的模型表示,實現的是一種無縫連線。而程序導向強調分析、設計及編碼之間按規則進行轉換貫穿於軟體生命週期的分析、設計及編碼中,實現的是一種有縫的連線。
物件導向和程序導向的特性和優缺點對比如表 1 所示。
表 1:物件導向和程序導向的特性和優缺點對比
|
物件導向 |
程序導向 |
特性 |
抽象、繼承、封裝、多型 |
功能模組化,程式碼流程化 |
優點 |
易維護、易復用、易擴充套件、低耦合 |
效能高,適合資源緊張、實時性強的場合 |
缺點 |
效能比程序導向低 |
沒有物件導向易維護、易復用、易擴充套件 |
物件導向的程式設計方法有四個基本特性:
1) 抽象:就是忽略一個主題中與當前目標無關的方面,以便更充分地注意與當前目標有關的方面。抽象並不打算了解全部問題,而只是選擇其中的一部分,暫時不用部分細節。抽象包括兩個方面,一是過程抽象,二是資料抽象。
過程抽象是指任何一個明確定義功能的操作都可被使用者看作單個的實體看待,儘管這個操作實際上可能由一系列更低階的操作來完成。資料抽象定義了資料型別和施加於該型別物件上的操作,並限定了物件的值,只能通過使用這些操作修改和觀察。
2) 繼承:這是一種聯結類的層次模型,並且允許和鼓勵類的重用,它提供了一種明確表述共性的方法。物件的一個新類可以從現有的類中派生,這個過程稱為類繼承。新類繼承了原始類的特性,新類稱為原始類的派生類(子類),而原始類稱為新類的基礎類別(父類別)。
派生類可以從它的基礎類別那裡繼承方法和範例變數,並且類可以修改或增加新的方法使之更適合特殊的需要。這也體現了大自然中一般與特殊的關係。繼承性很好地解決了軟體的可重用性問題。
3) 封裝:就是把過程和封包圍起來,對資料的存取只能通過已定義的介面。物件導向的計算始於這個基本概念,即現實世界可以被描繪成一系列完全自治、封裝的物件,這些物件通過一個受保護的介面存取其他物件。一旦定義了一個物件的特性,則有必要決定這些特性的可見性,即哪些特性對外部世界是可見的,哪些特性用於表示內部狀態。
在這個階段定義物件的介面。通常,應禁止直接存取一個物件的實際表示,而應通過操作介面存取物件,這稱為資訊隱藏。封裝保證了模組具有較好的獨立性,使得程式維護修改較為容易。對應用程式的修改僅限於類的內部,因而可以將應用程式修改帶來的影響減少到最低限度。
4) 多型:是指允許不同類的物件對同一訊息做出響應。比如同樣的複製-貼上操作,在字處理程式和繪圖程式中有不同的效果。多型性包括引數化多型性和包含多型性。多型性語言具有靈活、抽象、行為共用、程式碼共用的優勢,很好地解決了應用程式函數同名問題。
為了進一步理解物件導向和程序導向的不同,以設計一個五子棋程式為例,程序導向的設計思路是,首先分析問題的步驟:① 開始遊戲;② 黑子先走;③ 繪製畫面;④ 判斷輸贏;⑤ 輪到白子;⑥ 繪製畫面;⑦ 判斷輸贏;⑧ 返回步驟 ②;⑨ 輸出最後結果,然後將上面每個步驟用程式來實現即可。
物件導向的設計則將程式分為三類物件:① 黑白雙方,這兩方的行為是一模一樣的;② 棋盤系統,負責繪製畫面;③ 規則系統,負責判定諸如犯規、輸贏等。第 ① 類物件(玩家物件)負責接受使用者輸入,並告知第 ② 類物件(棋盤物件)棋子佈局的變化,棋盤物件接收到了棋子的變化就要負責在螢幕上面顯示出這種變化,同時利用第 ③ 類物件(規則系統)來對棋局進行判定。
可見,物件導向是以功能來劃分問題,而不是步驟。同樣是繪製棋局,這樣的行為在程序導向的設計中分散在了多個步驟中,很可能出現不同的繪製版本,而物件導向的設計中,繪圖只可能在棋盤物件中出現,從而保證了繪圖的統一。功能上的統一保證了物件導向設計的可延伸性。
如要加入悔棋功能,若是程序導向設計,則從輸入到判斷到顯示的若干步驟都要改動,甚至步驟之間的先後順序都可能需要調整。而若是物件導向設計,則只需改動第 ② 類物件(棋盤物件)即可,棋盤物件儲存了黑白雙方的棋譜和落子先後順序,簡單回溯操作即可實現悔棋功能,並不涉及顯示和規則部分,改動是區域性可控的。