| 規則 | 說明 |
| 只能出現在抽象類別中 | 非抽象類別不可包含 abstract 成員 |
| 不能有 static、virtual、private 修飾詞 | 隱含 virtual;預設可視性可為 public/protected/internal |
| 方法主體只能是分號 | 連 { } 都不允許 |
| 衍生類別必須 override | 除非衍生類別也是 abstract |
| 不能用 base 呼叫 | base.AbstractMethod() 編譯錯誤 (無實作可呼叫) |
完整範例:幾何圖形體系
public abstract class Shape
{
public abstract double Area { get; } // 抽象屬性 (C# 支援)
public abstract double CalculatePerimeter();
}
public class Circle : Shape
{
public double Radius { get; }
public Circle(double r) => Radius = r;
public override double Area => Math.PI * Radius * Radius;
public override double CalculatePerimeter() => 2 * Math.PI * Radius;
}
public class Rectangle : Shape
{
public double Width { get; }
public double Height { get; }
public Rectangle(double w, double h) { Width = w; Height = h; }
public override double Area => Width * Height;
public override double CalculatePerimeter() => 2 * (Width + Height);
}
抽象方法覆寫虛方法:攔截預設行為
public class Base
{
public virtual void Foo() => Console.WriteLine("Base.Foo");
}
public abstract class Middle : Base
{
// 以抽象方法「攔截」基類虛方法,強制進一步衍生類別實作
public abstract override void Foo();
}
public class Derived : Middle
{
public override void Foo() => Console.WriteLine("Derived.Foo");
}
此模式適用於:基類提供預設實作,但中間層希望強制子類別自訂行為 (如 Template Method 模式變體)。
抽象方法 vs. 介面方法
| 特性 | 抽象方法 | 介面方法 |
| 所屬類型 | abstract class | interface |
| 可有實作成員 | 是 | C# 8.0 前否,之後可有預設實作 |
| 繼承方式 | 單一繼承 | 多重實作 |
| 建構函式 | 可有 | 不可有 |
| 存取修飾詞 | 可指定 | 隱含 public |
常見錯誤與除錯
// 錯誤 1:抽象方法加上 virtual
public abstract virtual void Foo(); // CS0506
// 錯誤 2:抽象方法有主體
public abstract void Foo() { } // CS0501
// 錯誤 3:衍生類別未 override
public class Bad : Shape { } // CS0534: 不實作抽象成員
// 錯誤 4:base 呼叫抽象方法
public class Derived : Base {
public override void Foo() { base.Foo(); } // CS0115: base.Foo 是抽象的
}
設計指引
- 當「預設行為無意義」或「必須由子類別賦予領域意義」時,使用抽象方法
- 搭配抽象類別建構函式,強制子類別傳入必要參數
- 考慮介面 + 抽象基類組合:介面定義契約,抽象類別提供共用實作
- 上一篇文章: C# 解析 WAV 檔案標頭:BinaryReader 讀取 RIFF/WAVE/fmt/data Chunk 結構
- 下一篇文章: C# 抽象類別深度解析:定義規則、實例化限制與繼承鏈實作
Copyright ©
程式碼之家 All Rights Reserved