首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

C++ 物件導向三大支柱:封裝、繼承、多態深度解析

     編輯:關於C++

封裝:資料與行為的邊界

將資料 (成員變數) 與操作資料的函數 (成員函數) 綁定在類別內部,並透過存取權限 (public/protected/private) 隱藏實作細節。

兩層含義

  1. 聚合:相關資料與操作封裝成獨立單元 (類別),物件間互不干擾。
  2. 資訊隱藏:private 成員僅供類別內部存取,對外暴露極少 public 介面。

優勢

  • 降低複雜度:使用者只需知道做什麼 (介面),不知怎麼做 (實作)。
  • 易維護:內部變更不影響外部呼叫端 (介面不變)。
  • 復用性:類別可被實例化多次、被繼承擴展。
  • 安全性:防止外部任意修改內部狀態導致不一致。

繼承:站在巨人肩膀上

衍生類別 (子類別) 繼承基底類別 (父類別) 的資料成員與成員函數,並可新增、覆寫、隱藏 父類別成員。

核心價值:軟體復用

  • 避免重複造輪子,減少程式碼重複。
  • 建立is-a 語意關係:Dog : Animal、Car : Vehicle。
  • 多型基礎:基底類別指標/參考指向衍生物件。

繼承類型

類型語法特點
公有繼承class D : public B保留基底介面語意,is-a 關係
保護繼承class D : protected B基底 public/protected 變 protected
私有繼承class D : private B基底所有成員變 private,實作細節復用
多重繼承class D : public B1, public B2繼承多個基底,需解決菱形問題
虛擬繼承class D : virtual public B解決菱形繼承資料重複與二義性

多態:同一介面,多種行為

同一訊息 (函數呼叫) 作用於不同物件產生不同行為。分靜態多態 (編譯期) 與動態多態 (執行期)。

靜態多態 (編譯期綁定)

  • 函數重載:同名不同參數,編譯期依實參選擇。
  • 運算子重載:賦予運算子新語意。
  • 模板:泛型程式設計,編譯期具現化具體型別程式碼。

動態多態 (執行期綁定 / 延遲綁定)

  • 條件:公有繼承 + 虛擬函數 + 基底指標/參考操作衍生物件。
  • 機制:虛函數表 (vtable) + 虛指標 (vptr),執行期查表分派。
  • 關鍵字:virtual、override (C++11)、final (C++11)。

範例:動物叫聲

class Animal {
public:
    virtual void speak() const { cout << "Animal sound\n"; }
    virtual ~Animal() {}  // 虛擬解構函數,必須!
};

class Dog : public Animal {
public:
    void speak() const override { cout << "Woof!\n"; }
};

class Cat : public Animal {
public:
    void speak() const override { cout << "Meow~\n"; }
};

void makeSound(const Animal& a) { a.speak(); }  // 參考多態

int main() {
    Dog d; Cat c;
    makeSound(d);  // Woof!
    makeSound(c);  // Meow~
    Animal* p = new Dog();
    p->speak();    // Woof!
    delete p;
}

虛擬解構函數鐵律

基底類別若有虛擬函數,解構函數必須宣告為 virtual。否則 delete 基底指標 僅呼叫基底解構函數,衍生部分資源洩漏。

三大支柱協作關係

graph TD A[封裝] --> B[繼承] A --> C[多態] B --> C C --> D[靈活/可擴充/可維護系統]
  • 封裝 定義清晰邊界,讓繼承與多態有乾淨的介面可依賴。
  • 繼承 建立類別層次,提供多態所需的「基底指向衍生」結構。
  • 多態 讓演算法依抽象介面而非具體型別編程,實現開放封閉原則 (對擴充開放、對修改關閉)。

現代 C++ 最佳實踐

  1. 預設成員 private,最小化介面。
  2. 組合優於繼承 (has-a > is-a),除非確立 is-a 語意。
  3. 覆寫虛擬函數加 override,編譯器檢查簽名一致。
  4. 最終類別/函數加 final 防止進一步繼承/覆寫。
  5. 介面類別 (純虛擬類別) 定義契約,實作類別繼承實作。
  6. 避免深層繼承樹 (超過 3 層通常設計有問題)。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved