| 規則 | 說明 |
abstract 修飾符 | 類別宣告加 abstract,明確標示不可實例化 |
| 不可實例化 | new AbstractClass() 編譯錯誤;變數只能為 null 或指向衍生類實例 |
| 可包含抽象成員 | abstract 方法/屬性/事件/索引子;非強制(可全為具體) |
不可為 sealed | abstract sealed 衝突:abstract 要求繼承,sealed 禁止繼承 |
| 衍生類強制實作 | 非抽象衍生類必須以 override 實作所有繼承的抽象成員 |
二、抽象成員語法
abstract class Animal
{
// 抽象方法:無主體,分號結尾
public abstract void Speak();
// 抽象屬性:只有存取器宣告
public abstract string Name { get; set; }
// 具體方法:可提供預設實作
public void Breathe() => Console.WriteLine("Breathing...");
// 具體屬性
public int Age { get; set; }
}
三、強制實作鏈範例
abstract class A
{
public abstract void F();
}
abstract class B : A
{
// B 未實作 F,所以 B 也必須是 abstract
public void G() { }
}
class C : B
{
// C 非抽象,必須實作 F
public override void F()
{
Console.WriteLine("C implements F");
}
}
關鍵點
A 定義抽象 F
B 繼承 A 但未實作 F → B 必須也是 abstract
C 繼承 B 並實作 F → C 可為具體類別
四、Vehicle 範例重構:抽象類別實戰
重構前:具體基類
class Vehicle { ... } // 可實例化,但「交通工具」是抽象概念
重構後:抽象基類
using System;
abstract class Vehicle
{
public int Wheels { get; protected set; }
protected float Weight { get; set; }
protected Vehicle(int w, float g) { Wheels = w; Weight = g; }
// 抽象方法:強制衍生類實作
public abstract void Speak();
// 具體方法:共享邏輯
public void Move() => Console.WriteLine($"Moving with {Wheels} wheels...");
}
class Car : Vehicle
{
public int Passengers { get; set; }
public Car(int w, float g, int p) : base(w, g) { Passengers = p; }
public override void Speak() => Console.WriteLine("Car: Di-di!");
}
class Truck : Vehicle
{
public int Passengers { get; set; }
public float Load { get; set; }
public Truck(int w, float g, int p, float l) : base(w, g) { Passengers = p; Load = l; }
public override void Speak() => Console.WriteLine("Truck: Ba-ba!");
}
使用效果
// Vehicle v = new Vehicle(); // 編譯錯誤:無法實例化抽象類別
Vehicle v1 = new Car(4, 1.5f, 5);
Vehicle v2 = new Truck(6, 5f, 2, 10f);
v1.Speak(); // Car: Di-di!
v2.Speak(); // Truck: Ba-ba!
v1.Move(); // 共享基類具體方法
五、抽象類別 vs 介面:深度比較
| 特性 | 抽象類別 | 介面 |
| 關鍵字 | abstract class | interface |
| 實作繼承 | 單一繼承 | 多重實作 |
| 成員類型 | 抽象 + 具體(欄位、方法、屬性、建構函式) | 僅簽章(C# 8+ 可有預設實作) |
| 存取修飾符 | 完整支援 | 隱含 public(C# 8+ 可 private) |
| 建構函式 | 可有(供衍生類呼叫 base()) | 不可有 |
| 適用場景 | 「是一種」關係、共享程式碼、版本演進 | 「能做什麼」契約、多重實作、跨層級解耦 |
選擇指南
- 需要共享程式碼(欄位、建構函式、具體方法)→ 抽象類別
- 定義純行為契約、支援多重實作、跨組件解耦 → 介面
- 現代 C#:介面可有預設實作(
default),界限模糊化,但語意不同
六、C++ vs C# 抽象類別差異
C++:無 abstract 關鍵字,類別含純虛擬函數(virtual void F() = 0;)即為抽象類別。語法隱晦、易誤解。
C#:明確 abstract class、abstract method,語意清晰、編譯器強制檢查。
七、總結
抽象類別是「不完整的基類」:
abstract 明確宣告不可實例化
- 可混合抽象與具體成員,提供共享實作 + 強制契約
- 非抽象衍生類必須實作所有抽象成員
- 單一繼承,適合「是一種」關係與程式碼重用
- 配合介面使用:抽象類別提供骨架,介面定義契約
- 上一篇文章: C# 多型核心概念總覽:虛擬方法、覆寫、抽象類別三大支柱
- 下一篇文章: C# 讀取 WAVE 檔案標頭資訊完整程式碼:RIFF 結構、位元解析、BitConverter 應用
Copyright ©
程式碼之家 All Rights Reserved