多態:同一操作作用於不同物件時,表現出不同行為。「一個介面,多種實作」。
virtual 標記可被覆寫的方法override 提供專屬實作
public abstract class Animal
{
public string Name { get; set; }
protected Animal(string name) => Name = name;
// 虛擬方法:提供預設實作,允許子類別重寫
public virtual void Shout()
{
Console.WriteLine($"我是動物:{Name}");
}
// 抽象方法:強制子類別實作,無預設行為
public abstract void Move();
}
public class Cat : Animal
{
public Cat(string name) : base(name) { }
public override void Shout() // 重寫:完全取代父類實作
{
Console.WriteLine($"喵~ 我是 {Name}");
}
public override void Move() => Console.WriteLine($"{Name} 靜悄悄地走");
}
public class Dog : Animal
{
public Dog(string name) : base(name) { }
public override void Shout()
{
Console.WriteLine($"汪!我是 {Name}");
}
public override void Move() => Console.WriteLine($"{Name} 搖著尾巴跑");
}
public class Bird : Animal
{
public Bird(string name) : base(name) { }
// 不重寫 Shout(),使用父類預設實作
public override void Move() => Console.WriteLine($"{Name} 飛上藍天");
}
var animals = new Animal[]
{
new Cat("小花"),
new Dog("大黃"),
new Bird("小鳥")
};
foreach (var animal in animals)
{
animal.Shout(); // 動態綁定:執行實際物件類型的方法
animal.Move();
Console.WriteLine();
}
/* 輸出:
喵~ 我是 小花
小花 靜悄悄地走
汪!我是 大黃
大黃 搖著尾巴跑
我是動物:小鳥 (Bird 未重寫 Shout,使用父類虛擬方法)
小鳥 飛上藍天
*/
| 特性 | virtual | abstract |
|---|---|---|
| 方法主體 | 有預設實作 | 無實作 (分號結尾) |
| 子類別重寫 | 可選 | 強制 |
| 類別修飾詞 | 可用於非抽象類別 | 僅限 abstract 類別 |
| 呼叫基底實作 | base.Method() | 無基底實作 |
virtual/abstract/override 方法參與動態綁定Animal animal = new Cat())
public class Base
{
public virtual void Method() { }
}
public class Derived : Base
{
// 密封:禁止進一步重寫
public sealed override void Method() { }
}
public class Further : Derived
{
// 錯誤:無法重寫 sealed 方法
// public override void Method() { }
// 新增:隱藏基底方法 (非多態,靜態綁定)
public new void Method() { }
}
public interface IShape
{
double Area();
}
public class Circle : IShape
{
public double Radius { get; set; }
public double Area() => Math.PI * Radius * Radius;
}
public class Rectangle : IShape
{
public double Width { get; set; }
public double Height { get; set; }
public double Area() => Width * Height;
}
// 使用
IShape[] shapes = { new Circle { Radius = 2 }, new Rectangle { Width = 3, Height = 4 } };
foreach (var s in shapes) Console.WriteLine(s.Area());
| 誤區 | 正確認知 |
|---|---|
| 多態 = 繼承 | 多態需要繼承,但繼承不一定產生多態 (需虛方法) |
| 所有方法都是多態的 | 只有 virtual/abstract/override 方法 |
| 父類別參考只能呼叫父類別方法 | 父類別參考呼叫虛方法會執行子類別實作 |
| new 關鍵字實現多態 | new 是隱藏 (靜態綁定),非多態 |
多態是物件導向設計靈活性的核心,善用虛擬方法與介面,讓系統擁有「開放擴充、封閉修改」的擴展能力。