在 C# 中,當方法使用 virtual 修飾符聲明時,該方法即為「虛擬方法」;反之則為「非虛擬方法」。虛擬方法允許派生類透過 override 關鍵字改寫其執行邏輯,從而實現多態;而非虛擬方法無論由基類實例或派生類實例呼叫,執行行為均保持不變。值得注意的是,標記為 virtual 的方法不可同時使用 static、abstract 或 override 修飾符。
以下範例展示虛擬方法 G() 與非虛擬方法 F() 的行為差異:
using System;
class A
{
public void F() { Console.WriteLine("A.F"); }
public virtual void G() { Console.WriteLine("A.G"); }
}
class B : A
{
// 使用 new 隱藏基類非虛擬方法
public new void F() { Console.WriteLine("B.F"); }
// 使用 override 重寫虛擬方法
public override void G() { Console.WriteLine("B.G"); }
}
class Test
{
static void Main()
{
B b = new B();
A a = b; // 向上轉型
a.F(); // 輸出: A.F (非虛擬,依據參考型別)
b.F(); // 輸出: B.F (非虛擬,依據實際型別)
a.G(); // 輸出: B.G (虛擬,動態繫結至實際型別)
b.G(); // 輸出: B.G (虛擬,動態繫結至實際型別)
}
}
new 關鍵字:僅隱藏基類成員,不影響多態行為;透過基類參考呼叫時仍會執行基類版本。override 關鍵字:擴展虛擬方法,實現真正的多態;透過基類參考呼叫時會執行派生類版本。範例中 a.G() 實際呼叫 B.G,正是因為編譯時型別為 A,但執行時型別為 B,CLR 根據實際物件型別分派方法,這正是多態的核心機制。