| 關鍵字 | 機制 | 基類參考指向衍生物件時 | 衍生類別參考指向衍生物件時 |
|---|---|---|---|
override | 虛擬方法多型(動態繫結) | 呼叫衍生類別實作 | 呼叫衍生類別實作 |
new | 方法隱藏(靜態繫結) | 呼叫基類實作 | 呼叫衍生類別實作 |
// 基類
public class Customer {
public virtual string GetFunnyString() {
return "Plain ordinary customer. Kaark!";
}
}
// 衍生類別:使用 override
public class Nevermore60Customer : Customer {
public override string GetFunnyString() {
return "Nevermore60.Nevermore!";
}
}
// 衍生類別:使用 new(隱藏)
public class HiddenCustomer : Customer {
public new string GetFunnyString() {
return "Hidden version!";
}
}
Customer c1 = new Nevermore60Customer();
Nevermore60Customer c2 = new Nevermore60Customer();
Console.WriteLine(c1.GetFunnyString()); // 輸出: Nevermore60.Nevermore! (多型生效)
Console.WriteLine(c2.GetFunnyString()); // 輸出: Nevermore60.Nevermore!
// --- 隱藏版本 ---
Customer h1 = new HiddenCustomer();
HiddenCustomer h2 = new HiddenCustomer();
Console.WriteLine(h1.GetFunnyString()); // 輸出: Plain ordinary customer. Kaark! (基類版本!)
Console.WriteLine(h2.GetFunnyString()); // 輸出: Hidden version!
override:衍生類別方法標記 `virtual final`,基類方法為 `virtual`。呼叫端發 `callvirt` 指令,執行期依物件實際型別分派。new:衍生類別方法為非虛擬(預設 `non-virtual`),基類方法不變。呼叫端發 `call` 指令,編譯期依**宣告型別**繫結。使用 `new` 隱藏繼承成員時,編譯器會發出警告:
'HiddenCustomer.GetFunnyString()' hides inherited member 'Customer.GetFunnyString()'. Use the new keyword if hiding was intended.
這提醒開發者確認是否為刻意隱藏,避免誤用。
override:符合里氏替換原則,保持多型一致性。new:例如第三方庫基類非虛擬方法需同名擴展、或刻意中斷多型行為。sealed override:防止進一步衍生類別再次覆寫,鎖定行為。
public interface IGreeter { void Greet(); }
public class Base : IGreeter {
public virtual void Greet() => Console.WriteLine("Base");
}
public class Derived : Base, IGreeter {
public override void Greet() => Console.WriteLine("Derived Override");
// 顯式介面實作(隱藏)
void IGreeter.Greet() => Console.WriteLine("Explicit Interface");
}
顯式介面實作同樣屬於「隱藏」語意:透過 `Base` 或 `Derived` 參考呼叫 `Greet()` 走多型;轉型為 `IGreeter` 才呼叫顯式實作。