C# 的虛擬方法機制是物件導向多型的核心。本文從方法繼承鏈的建立、關鍵字語意、到執行時期的動態分派流程,系統性剖析其運作原理,並透過實戰範例驗證推論。
方法宣告時可使用四個關鍵字控制繼承行為:
若無關鍵字,預設具有 new 行為(隱藏父類別同名方法),編譯器會發出警告建議明確指定。
從基類別到衍生類別,依序檢查各類別對方法的定義:
override 或 sealed 的定義成為繼承鏈起點virtual 的定義會被附加到鏈中new 即終止鏈(該方法不加入);遇到 sealed 加入後終止鏈當透過基類別參考呼叫衍生類別實例的方法時:
public class A {
public virtual void Foo1() { Console.WriteLine("A.Foo1()"); }
public void Foo2() { Console.WriteLine("A.Foo2()"); }
}
public class B : A {
public override void Foo1() { Console.WriteLine("B.Foo1()"); }
public new virtual void Foo2() { Console.WriteLine("B.Foo2()"); }
}
public class C : B {
public new void Foo1() { Console.WriteLine("C.Foo1()"); }
}
public class D : C {
public override sealed void Foo2() { Console.WriteLine("D.Foo2()"); }
}
測試碼與輸出:
C aD = new D(); A aC = new C();
aD.Foo1(); // C.Foo1() - 參考型別 C,Foo1 在 C 以 new 斷鏈
aD.Foo2(); // D.Foo2() - 參考型別 C,Foo2 鏈為 B→D,底端為 D
aC.Foo1(); // B.Foo1() - 參考型別 A,Foo1 鏈為 A→B,底端為 B
aC.Foo2(); // A.Foo2() - 參考型別 A,Foo2 非虛擬,直接呼叫 A 版本

善用 Visual Studio「重構→重命名」功能可直觀觀察繼承鏈中斷點,輔助理解與除錯。