抽象類別在繼承體系中扮演「共同祖先」角色,提供預設實作;介面則定義「原子化功能合約」,任何型別皆可實作。兩者各有千秋,核心差異在於:繼承表達「is-a」關係,介面表達「behaves-like」關係。基類描述物件是什麼,介面描述物件有什麼行為。
介面可包含方法、屬性、索引子、事件等佔位元素。實作介面的型別必須具體實作所有成員。介面不含任何實作邏輯與資料成員,純粹定義合約。優點在於:
IEnumerable vs CollectionBase 範例)。基類可提供具體實作、資料成員、虛擬方法等。向基類新增方法,所有衍生類自動獲得;但向介面新增方法會中斷所有現有實作類別。System.Collections.CollectionBase 即採混合策略:實作 IList、ICollection、IEnumerable 介面,並提供 OnInsert 等虛擬方法供衍生類自訂行為。
public class IntList : System.Collections.CollectionBase
{
protected override void OnInsert(int index, object value)
{
try
{
int newValue = System.Convert.ToInt32(value);
Console.WriteLine("Inserting {0} at position {1}", index, value);
}
catch (FormatException e)
{
throw new ArgumentException("Argument Type not an integer", "value", e);
}
}
protected override void OnInsertComplete(int index, object value)
{
Console.WriteLine("Inserted {0} at position {1}", index, value);
}
}
回傳介面而非具體類別(如 IListSource 取代 DataSet),可:
DataTable、DataView 或自訂型別)不破壞公開介面。Employee、Customer、Vendor 皆實作 IContactInfo)。實作介面的實值型別(如 URLInfo : IComparable)在裝箱後,透過介面呼叫方法可避免拆箱左側物件,減少效能開銷。
基類適合描述「相關型別的共用行為與實作」;介面適合定義「不相關型別皆可實作的原子功能塊」。善用兩者差異,能創造表達力更強、面對修改更具彈性的設計。