| 項目 | 要求 | 說明 |
| 方法名稱 | 完全相同 | 區分大小寫 |
| 回傳型別 | 完全相同 | C# 不支援協變回傳型別 |
| 參數個數 | 完全相同 | |
| 參數型別與順序 | 完全相同 | 含 ref/out/in 修飾符 |
修飾符規則
- 必須加
override
- 禁止加
new、static、virtual
- 存取修飾符:不可比基類更嚴格(如基類
protected,衍生類不可 private)
二、完整多型範例:Vehicle → Car / Truck
using System;
// 基類:虛擬方法 Speak
class Vehicle
{
public int Wheels { get; set; }
protected float Weight { get; set; }
public Vehicle(int w, float g) { Wheels = w; Weight = g; }
public virtual void Speak()
{
Console.WriteLine("The vehicle is speaking!");
}
}
// 衍生類:Car
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("The car is speaking: Di-di!");
}
}
// 衍生類:Truck
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("The truck is speaking: Ba-ba!");
}
}
// 測試多型
class Test
{
public static void Main()
{
Vehicle v1 = new Vehicle(); // 基類實例
Car c1 = new Car(4, 2f, 5); // 衍生類實例
Truck t1 = new Truck(6, 5f, 3, 10f);
v1.Speak(); // 基類實例呼叫
v1 = c1; // 基類參考指向 Car 實例
v1.Speak(); // 多型:呼叫 Car.Speak()
c1.Speak(); // 直接呼叫
v1 = t1; // 基類參考指向 Truck 實例
v1.Speak(); // 多型:呼叫 Truck.Speak()
t1.Speak(); // 直接呼叫
}
}
執行結果
The vehicle is speaking!
The car is speaking: Di-di!
The car is speaking: Di-di!
The truck is speaking: Ba-ba!
The truck is speaking: Ba-ba!
三、多型核心機制分析
關鍵觀察
Vehicle v1 宣告為基類型別
v1 = c1:基類參考指向衍生類實例(向上轉型,隱含轉換)
v1.Speak():編譯期看靜態型別 Vehicle,執行期看動態型別 Car
- 虛擬方法表查找:
v1 內部 __vptr 指向 Car 的 vtable → 找到 Car.Speak 位址 → 執行
動態多型 vs 靜態多型
- 動態多型(執行期):虛擬方法覆寫,依實際物件型別決定行為
- 靜態多型(編譯期):方法多載、泛型、擴充方法,依靜態型別決定
四、常見錯誤與編譯器檢查
| 錯誤代碼 | 原因 | 範例 |
| CS0506 | 基類方法非虛擬,無法 override | 基類無 virtual,衍生類加 override |
| CS0115 | 方法簽章不匹配 | 參數型別不同、回傳型別不同 |
| CS0239 | override 與 new 衝突 | 同時加了兩個修飾符 |
| CS0505 | override 與 static 衝突 | 靜態方法屬於類別,非實例 |
五、進階:base 關鍵字呼叫基類實作
public override void Speak()
{
base.Speak(); // 先執行基類邏輯
Console.WriteLine("Car adds: Di-di!");
}
// 輸出:
// The vehicle is speaking!
// Car adds: Di-di!
六、總結
虛擬方法覆寫鐵律:
- 基類
virtual 宣告可覆寫
- 衍生類
override 實作,簽章完全一致
- 基類參考指向衍生類實例 → 呼叫虛擬方法 → 動態綁定 到衍生類實作
- 這就是執行期多型:同一介面,不同行為,由物件實際型別決定
掌握此機制,是設計可擴充、符合開放封閉原則(OCP)類別階層的基礎。
- 上一篇文章: C# 虛擬方法完整解析:virtual、override、new、多型行為與編譯期vs執行期綁定
- 下一篇文章: C# 多型核心概念總覽:虛擬方法、覆寫、抽象類別三大支柱
Copyright ©
程式碼之家 All Rights Reserved