C 物件導向程式設計的重要概念

2021-04-01 20:33:54 字數 3008 閱讀 6481

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 物件導向程式設計基本概念

繼承與派生 都是針對同一種技術現象的不同角度說法 子類繼承父類,父類派生出子類 繼承 乙個新類從已有的類那裡獲得其已有特性,這種現象稱為類的繼承。派生 從已有的類產生乙個新的子類 或稱為基類和派生類 多重繼承 乙個派生類有兩個或多個基類。派生類是基類的具體化,而基類是派生類的抽象。注 多重繼承的構造...

C 物件導向程式設計 複習重點概念

內聯函式 乙個函式,前面加有關鍵字inline。系統在編譯時,凡遇到呼叫內聯函式,則在實參替代形參後,用該函式中的全部 來代替被呼叫函式。語句較少,且被頻繁呼叫的函式可被定義為內聯函式。函式過載 指在同乙個命名空間內,多個函式可以擁有相同的名字。要求過載的函式至少在引數個數或引數型別上與已定義的函式...