C 物件導向程式設計

2021-04-01 20:34:59 字數 3008 閱讀 5817

1.1 類與物件

物件(object)是類(class)的乙個例項(instance)。如果將物件比作房子,那麼類就是房子的設計圖紙。所以物件導向程式設計的重點是類的設計,而不是物件的設計。類可以將資料和函式封裝在一起,其中函式表示了類的行為(或稱服務)。類提供關鍵字public、protected 和private 用於宣告哪些資料和函式是公有的、受保護的或者是私有的。

這樣可以達到資訊隱藏的目的,即讓類僅僅公開必須要讓外界知道的內容,而隱藏其它一切內容。我們不可以濫用類的封裝功能,不要把它當成火鍋,什麼東西都往裡扔。

類的設計是以資料為中心,還是以行為為中心?

主張「以資料為中心」的那一派人關注類的內部資料結構,他們習慣上將private 型別的資料寫在前面,而將public 型別的函式寫在後面,如表8.1(a)所示。

主張「以行為為中心」的那一派人關注類應該提供什麼樣的服務和介面,他們習慣上將public 型別的函式寫在前面,而將private 型別的資料寫在後面,如表8.1(b)所示。

很多c++教課書主張在設計類時「以資料為中心」。我堅持並且建議讀者在設計類時「以行為為中心」,即首先考慮類應該提供什麼樣的函式。microsoft 公司的com 規範的核心是介面設計,com 的介面就相當於類的公有函式[rogerson 1999]。在程式設計方面,咱們不要懷疑microsoft 公司的風格。

設計孤立的類是比較容易的,難的是正確設計基類及其派生類。因為有些程式設計師搞不清楚「繼承」(inheritance)、「組合」(composition)、「多型」( polymorphi**)這些概念。

1.2 繼承與組合

如果a 是基類,b 是a 的派生類,那麼b 將繼承a 的資料和函式。示例程式如下:

class a

;class b : public a

;// example

main()

這個簡單的示例程式說明了乙個事實:c++的「繼承」特性可以提高程式的可復用性。正因為「繼承」太有用、太容易用,才要防止亂用「繼承」。我們要給「繼承」立一些使用規則:

不要覺得「不吃白不吃」,讓乙個好端端的健壯青年無緣無故地吃人參補身體。

二、如果類b 有必要使用a 的功能,則要分兩種情況考慮:

(1)若在邏輯上b 是a 的「一種」(a kind of ),則允許b 繼承a 的功能。如男人(man)是人(human)的一種,男孩(boy)是男人的一種。那麼類man 可以從類human 派生,類boy 可以從類man 派生。示例程式如下:

class human

;class man : public human

;class boy : public man

;(2)若在邏輯上a 是b 的「一部分」(a part of),則不允許b 繼承a 的功能,而是要用a和其它東西組合出b。例如眼(eye)、鼻(nose)、口(mouth)、耳(ear)是頭(head)的一部分,所以類head 應該由類eye、nose、mouth、ear 組合而成,不是派生而成。示例程式如下:

class eye

;class nose

;class mouth

;class ear

;// 正確的設計,冗長的程式

class head

void **ell(void)

void eat(void)

void listen(void)

private:

eye m_eye;

nose m_nose;

mouth m_mouth;

ear m_ear;

};如果允許head 從eye、nose、mouth、ear 派生而成,那麼head 將自動具有look、**ell、eat、listen 這些功能:

// 錯誤的設計

class head : public eye, public nose, public mouth, public ear

;上述程式十分簡短並且執行正確,但是這種設計卻是錯誤的。很多程式設計師經不起「繼承」的**而犯下設計錯誤。

乙隻公雞使勁地追打乙隻剛下了蛋的母雞,你知道為什麼嗎?

因為母雞下了鴨蛋。 

1.3 虛函式與多型

除了繼承外,c++的另乙個優良特性是支援多型,即允許將派生類的物件當作基類的物件使用。如果a 是基類,b 和c 是a 的派生類,多態函式test 的引數是a 的 指標。那麼test 函式可以引用a、b、c 的物件。示例程式如下:

class a

;void test(a *a)

class b : public a

;class c : public a

;// example

main()

;以上程式看不出「多型」有什麼價值,加上虛函式和抽象基類後,「多型」的威力就顯示出來了。

c++用關鍵字virtual 來宣告乙個函式為虛函式,派生類的虛函式將(override)基類對應的虛函式的功能。示例程式如下:

class a

};void test(a *a)

class b : public a

};class c : public a

};// example

main()

;如果基類a 定義如下:

class a

;那麼函式func1 叫作純虛函式,含有純虛函式的類叫作抽象基類。抽象基類只管定義純虛函式的形式,具體的功能由派生類實現。

結合「抽象基類」和「多型」有如下突出優點:

(1)應用程式不必為每乙個派生類編寫功能呼叫,只需要對抽象基類進行處理即可。這一

招叫「以不變應萬變」,可以大大提高程式的可復用性(這是介面設計的復用,而不是**實現的復用)。

(2)派生類的功能可以被基類指標引用,這叫向後相容,可以提高程式的可擴充性和可維護性。以前寫的程式可以被將來寫的程式呼叫不足為奇,但是將來寫的程式可以被以前寫的程式呼叫那可了不起。

c 物件導向程式設計 物件導向

什麼是物件導向 是對現實世界理解和抽象的方法。物件導向程式設計的特點 易維護,易擴充套件,靈活性好,重用 類 對事物的抽象定義,即事物具有的共同特徵和行為。物件 即對類進行例項 類是抽象的,物件是具體的 類的定義 語法 訪問修飾符 class 類名類的成員 包括字段,屬性,方法,常量,事件和索引器等...

C 物件導向程式設計

物件導向程式設計 以物件為中心,將資料和方法封裝在一起。三要素 抽象繼承 多型 五個基本原則 單一職責原則 就乙個類而言,應該有且僅有乙個引起它變化的原因。開放 封閉原則 是說軟體實體 類 模組 函式等等 應該可以擴充套件,但是不可修改。黎克特制替換換原則 子類應當可以替換父類並出現在父類能夠出現的...

c 物件導向程式設計

這裡強調是物件導向程式設計的易錯點和常用技巧,嚴格來說大多數時候使用的封裝和繼承來完成的物件程式設計只能算是基於物件的程式設計,結合物件的繼承和多型特性編寫的程式才算是物件導向程式設計。繼承涉及到一些複製控制特性,主要如下 a 不顯式呼叫父類建構函式時,子類建構函式會先隱式呼叫父類預設建構函式 b ...