嗨嗨,今天要來介紹的,是 Interface, Abstract 和 Virtual 之間的關係。
它們概念上都是希望不同的類別能實作特定方法,但又有差異之處,請見下方的重點介紹 ~
用在組合 (Composition) 上面。組合是表示 has a 關係,無論類別是不是類似的東西,要實作該介面時,必須要實作特定的方法。
例如汽車 (car) 和自行車 (bicycle),雖然是不同類型的交通工具 (彼此間沒有繼承關係),只要實作 IVehicle
介面,就必須實作轉彎功能 (Turn) …。
用在繼承 (Inheritance) 上面。繼承是 is a 關係,宣告為 Abstract
的類別,應該是繼承父類別特性的子類別,必須維持和 Abstract
類別一樣的功能。
不能實作程式邏輯,且一定要被 Override。
例如汽車 (Car) 可以是一個 Abstract
類別,並要求實作加速 (Accelerate) 的方法,Taxi 子類別繼承時,也必須實作加速功能。
在被繼承的父類別內,可以先用 Virtual
實作方法內的邏輯。子類別繼承後,可以選擇要不要 Override,以複寫原本的功能。
不過被 Override 後,還是可以呼叫 base.xxx()
,來套用原先的邏輯。
例如汽車加速的動作,通常都是踩油門,可以先在 Virtual
方法內實作踩油門的動作,讓大部分繼承汽車的子類別使用。就算某天出了未來概念車 (Future Car),是用方向盤的按鈕加速,一樣可以實作在 Accelerate 方法內。
public class VehicleExample : IExample
{
protected interface IVehicle
{
public string Turn();
}
protected abstract class Car : IVehicle
{
public string Turn()
{
return "旋轉方向盤";
}
public virtual string Accelerate()
{
return "踩油門";
}
}
protected class Bicycle : IVehicle
{
public string Turn()
{
return "轉動握把";
}
}
protected class Taxi : Car
{
}
protected class FutureCar : Car
{
public override string Accelerate()
{
return "按下加速鈕";
}
}
public void Run()
{
Bicycle bicycle = new Bicycle();
Taxi taxi = new Taxi();
FutureCar futureCar = new FutureCar();
Console.WriteLine(bicycle.Turn()); // 輸出:轉動握把
Console.WriteLine(taxi.Turn()); // 輸出:旋轉方向盤
Console.WriteLine(futureCar.Turn()); // 輸出:旋轉方向盤
Console.WriteLine(taxi.Accelerate()); // 輸出:踩油門
Console.WriteLine(futureCar.Accelerate()); // 輸出:按下加速鈕
}
}
超好玩 ~