C# 多態機制要求明確使用 virtual、override、new 關鍵字,提供比 Java/C++ 更清晰、安全的版本控制與意圖表達。
| 關鍵字 | 用途 | 必要性 |
|---|---|---|
virtual | 基底類別方法標記為可覆寫 | 基底類別必須 |
override | 衍生類別實作覆寫 | 衍生類別必須 |
new | 隱藏基底成員 (非多態) | 選擇性 (編譯器警告) |
abstract | 強制衍生類別實作 | 抽象類別/方法 |
sealed | 禁止進一步覆寫 | 選擇性 |
public class Base {
public virtual void Foo() => Console.WriteLine("Base.Foo");
}
public class Derived : Base {
public override void Foo() => Console.WriteLine("Derived.Foo");
}
public class Hiding : Derived {
public new void Foo() => Console.WriteLine("Hiding.Foo");
}
// 使用
Base b = new Base(); b.Foo(); // Base.Foo
Base d = new Derived(); d.Foo(); // Derived.Foo (多態)
Base h = new Hiding(); h.Foo(); // Derived.Foo (多態,未覆寫)
Hiding h2 = new Hiding(); h2.Foo(); // Hiding.Foo (靜態繫結)
((Derived)h2).Foo(); // Derived.Foo
((Base)h2).Foo(); // Derived.Foo
override 非 virtual 方法 → 編譯錯誤override sealed 方法 → 編譯錯誤override 覆寫虛擬方法 → 編譯警告 (建議加 new)virtual 方法不可為 static、private (可 protected virtual)| 特性 | Java | C++ | C# |
|---|---|---|---|
| 預設虛擬 | 是 (非 final/private/static) | 否 (需 virtual) | 否 (需 virtual) |
| 覆寫標記 | @Override (選擇性註解) | 無 (C++11 有 override) | override (強制) |
| 隱藏基底 | 同名方法自動隱藏 | 同名函式隱藏 | new 關鍵字明確隱藏 |
| 版本安全 | 脆弱 (基底新增虛擬方法可能衝突) | 脆弱 | 強健 (override 明確意圖) |
// 基底類別 v1
public class Base {
public void Foo() { } // 非虛擬
}
// 衍生類別 v1
public class Derived : Base {
public void Foo() { } // 隱藏基底 (編譯器警告,建議加 new)
}
// 基底類別 v2 - 新增虛擬方法
public class Base {
public virtual void Foo() { } // 現在是虛擬
}
// C# 行為:Derived.Foo 仍為隱藏 (new),不會意外變成覆寫
// Java 行為:Derived.Foo 自動變成覆寫,可能導致行為改變
public abstract class Animal {
public abstract void MakeSound(); // 強制實作
public virtual void Sleep() => Console.WriteLine("Sleeping"); // 可選覆寫
}
public interface IFlyable {
void Fly(); // 隱含 public abstract
}
// 實作
public class Bird : Animal, IFlyable {
public override void MakeSound() => Console.WriteLine("Tweet");
public override void Sleep() => Console.WriteLine("Bird sleeping");
public void Fly() => Console.WriteLine("Flying");
}
public class Base {
public virtual void Foo() { }
}
public class Derived : Base {
public sealed override void Foo() { } // 禁止進一步覆寫
}
public class Further : Derived {
// public override void Foo() { } // 編譯錯誤
public new void Foo() { } // 僅能 new 隱藏
}
virtualoverride,編譯器強制保證new,消除警告並表達意圖sealed override 鎖定繼承鏈終點virtual/sealedC# 透過 virtual/override/new/sealed 明確表達多態意圖,編譯器強制驗證提供版本安全。這比 Java 隱含虛擬、C++ 隱含隱藏更安全、更易維護。理解這套機制,是設計可擴展、穩健類別階層的基礎。