純虛函數 (virtual ReturnType Func() = 0;) 定義**介面契約**而非實作,含純虛函數的類別為**抽象類別** (不可實例化)。本文詳細說明純虛函數語法、抽象類別特性、衍生類強制實作規則、純虛函數**可有函數本體**的冷知識、以及設計模式中的應用場景。
class Animal {
public:
void eat() { cout << "animal eat\n"; }
void sleep() { cout << "animal sleep\n"; }
virtual void breathe() = 0; // 純虛函數:= 0 表示無預設實作
};
// Animal 為抽象類別
// Animal an; // 編譯錯誤:cannot instantiate abstract class
class Fish : public Animal {
public:
void breathe() { cout << "fish bubble\n"; } // 必須實作,否則 Fish 也成抽象類別
};
class Shark : public Fish {
// 未實作 breathe() → 繼承 Fish 版本,可實例化
};
class Base {
public:
virtual void interface() = 0; // 宣告為純虛
};
// 類別外提供定義 (合法但罕見)
void Base::interface() {
cout << "Base default implementation\n";
}
class Derived : public Base {
public:
void interface() {
Base::interface(); // 可呼叫基類純虛函數實作
cout << "Derived extra\n";
}
};
用途:提供**預設通用邏輯**,衍生類可選擇呼叫 Base::interface() 復用,但**仍強制衍生類覆寫** (因宣告處 = 0)。
| 概念 | C++ 抽象類別 | Java/C# Interface |
|---|---|---|
| 可含資料成員 | 是 | 否 (僅常數) |
| 可含非虛函數 | 是 | 否 (Java 8+ 可有 default/static) |
| 可含建構函數 | 是 (供衍生類呼叫) | 否 |
| 多重繼承 | 支援 (需注意菱形繼承) | 支援 (介面多重實作) |
| 核心目的 | 定義契約 + 共享實作/狀態 | 純契約 |
class SortStrategy {
public:
virtual void sort(vector&) = 0;
};
class QuickSort : public SortStrategy { void sort(...) override { ... } };
class MergeSort : public SortStrategy { void sort(...) override { ... } };
class Sorter {
SortStrategy* strategy_;
public:
void setStrategy(SortStrategy* s) { strategy_ = s; }
void sortData(vector& v) { strategy_->sort(v); }
};
class Algorithm {
public:
void run() { // 模板方法 (非虛)
step1(); // 固定流程
step2(); // 可變部分 → 純虛
step3();
}
protected:
virtual void step2() = 0; // 子類必須實作
void step1() { ... }
void step3() { ... }
};
將大介面拆分為多個純虛類別 (如 IPrintable, ISerializable, IDrawable),類別僅繼承所需介面,避免「胖介面」強制實作不需方法。
關鍵區別:
virtual void foo() (虛函數) → 提供預設實作,**可選擇性覆寫**,支援多態。virtual void foo() = 0 (純虛函數) → **強制覆寫**,定義契約,同樣支援多態 (因本質仍是虛函數)。衍生類覆寫虛函數時,**無論是否寫 virtual**,皆為虛函數 (建議加 override)。
純虛函數 = 0 是 C++ 定義**介面契約**的核心工具。抽象類別不可實例化,衍生類**必須**實作所有純虛函數。純虛函數可提供預設實作供衍生類呼叫。廣泛應用於策略、模板方法、介面隔離等設計模式。**多態本質來自虛函數機制**,純虛函數只是「強制覆寫」的虛函數特例。