文章程式碼顯示

2018年3月2日 星期五

《筆記》談談C++語言 - 前言:物件導向概論


C 語言是屬於程序式的 動作導向設計( action oriented ) 。在 C 語言中,程式設計的 單元 就是 函式(function) ,我們會專注在 函式 的撰寫。

然而,真實世界的所有東西都可視為 object(物件) :人、動物、植物、汽車 ... 等等。而一個物件都會有其屬性(attribute):大小、形狀、顏色、重量;也會有行為(behavior):球能滾動、汽車能加速、人會走路 ....

物件導向設計( Object-oriented design, OOD) 是我們企圖使用程式碼建立一個模型,用來描述(模擬、模仿)這些物件的各種行為與屬性

物件導向設計的設計核心單位是 類別(class)

有別於 物件(object) ,類別更像是一個物件(實體)的藍圖。使用 類別 來進行設計時有一個很重要的優點,在於不同類別之間可能會有高度的相似性是可以被重復利用的,例如 敞篷車 跟 汽車。

思考一下,敞篷車當然會囊括了汽車的特徵(有輪子、有方向盤 ... )

換個角度,我們可以說 敞篷車類別 繼承了 汽車類別 的特徵,也就是當我們想創建一個新的類別(敞篷車)時,可以透過吸收現存類別(汽車)的特性再加上自己獨有的性質(敞篷車的車頂是可以掀開的),就完成了 敞篷車類別 的設計。

物件導向設計會將 屬性 以及 行為 封裝成物件,讓物件的 屬性 以及 行為 緊密結合在一起

物件具有資訊隱藏(information hiding) 的特性。這表示 物件 雖知如何透過已定義的介面(interface) 來與其它不同的 物件 進行溝通,但兩個不同的物件之間是無法得知彼此的 實作方式。

這麼說好像有點抽像,我們可以舉個例子。想像 人 是一個物件,ATM 提款機 是另一個物件。我們可以透過螢幕( ATM 提款機的已定義介面 ) 來跟 ATM 進行溝通以及提領現金,但我們並不知道內部的機器究竟是怎樣運作的

再舉一個例子, 人 可以跟 汽車 來進行溝通。當我們踩下汽車的油門時車子就會前進,但我們並不知道車子內部是怎樣讓車子前進的,只要懂得油門跟剎車(介面)就好,什麼引擎、傳動機構 ... 等等的都不需要了解。

這是物件導向設計一個很重要的概念:物件具有 資訊隱藏 的特性,會把實作細節進行隱藏

C++ 就是典型的物件導向程式語言,以這種程式語言進行設計就稱為 物件導向程式設計(object-oriented programming, OOP)

C++ 程式設計的 單元是 類別(class) 而不是函式(function)
我們可以從 類別 實體化(instantiated) 出物件,或我們可以說是 建立 一個物件(object) 

而一個物件裡面會包含了函式以及資料,函式實作了行為(behavior);資料實作了屬性(attribute)

實際上在 C++ 撰寫一個 類別(class) 就是在 建立一個自訂型別(user-defined types) ,每個類別含有資料(屬性)以及一些操作這些資料提供服務的函式(與 C 語言的 struct 很像)。

前面提到了行為(behavior) 是沿用了 OOD 的說法,在 C++ 中更常看到的是將類別的資料(屬性)部分稱為 資料成員(data member) ,例如我們創建一個 提款機 類別,則可能裡面的資料成員會有 客戶帳號、帳戶餘額 .... 等等

類別中的函式(行為) 部份在 C++ 稱為 成員函式(member function) ,通常在其它物件導向程式語言(例如 java) 會稱為 方法(method) 。再以 提款機 類別舉例,可能有 存款、提款、餘額查詢 ... 等等的成員函式



在這裡我們要停下腳步思考一下 類別跟物件 差在哪裡?

實際上 類別是一個 藍圖物件才是實體

舉例來說我們創建了一個 小木屋 類別,這是一個藍圖(建築圖)。當我們真正把這個房子蓋起來,才算是建立(實體化) 一個物件

一般而言一個完整的 C++ 程式會由一個 main 函式以及 一個或數個 類別(class) 所組成,每個類別均有資料成員以及成員函式

假如我們想創建一個 汽車 的物件該怎麼做呢?

總該先有藍圖吧 ! 所以我們先要做的是 建立一個 汽車類別,並且我們要設計一個介面,這個介面含有 加速、減速、轉向 ... 等等機制

某種程度上,油門隱藏了複雜的加速機制;剎車隱藏了減速機制;轉向隱藏的轉向機制,若我們能設計出一個好的介面來讓不懂汽車設計的人也能開這台車,我們就必須要讓使用者只需要透過 介面 操縱 油門、剎車 就可以控制這台汽車

透過介面我們可以去操控(呼叫)成員函式,而這些函式(方法)就描述了實際工作的機制,並將其執行的複雜工作隱藏起來,讓使用者看不到

要如何撰寫這個介面呢? 我們從建立 類別(class) 這個程式單位開始

類別會具有成員函式,就像汽車有油門;提款機有提款按鈕一樣

我們無法「駕駛」一張汽車的藍圖,但我們可以實實在在的「駕駛」一台汽車;同樣地,在程式執行類別所描述的工作前,也要先 建立(實體化) 出類別的物件。

順道一提,一張汽車的藍圖可以造出很多台汽車。

當我們建立(實體化) 汽車 這個物件後,就只要管發送一個訊息(message)  給物件,這叫做 成員函式呼叫(member-function call) 或稱 物件要求服務(requesting a service from an object) ,它會要求物件裡面的成員函式進行工作

當我們建立一個 汽車物件 後,理應當也會有該車輛的 屬性 ,也就是資料成員 如: 顏色、油箱大小、剩餘油量、里程數 ... 等等 這些屬性會跟著這輛車在路上跑,每一輛車都會有自己獨有的屬性。

物件之間並不會知道其它物件的屬性,舉例來說我們實體化了兩台 汽車物件 ,但這兩台車之間並不會知道彼此剩餘的油量、里程數 ... 等等

開發環境設置請見此連結

↓↓↓ 連結到部落格方針與索引 ↓↓↓

Blog 使用方針與索引