抽象類別在繼承中提供通用「祖先」。介面描述可被其他型別實作的原子級泛型功能。各有千秋,卻不盡相同。介面是合約式設計:實作某介面的型別,必須實作期望方法。抽象類別為相關類別集合提供通用抽象方法。老生常談:繼承是「is a」,介面是「behaves like」。基類描述物件是什麼,介面描述物件有某種行為。
介面描述一組功能集合或合約。可在介面建立任何佔位元素:方法、屬性、索引子、事件。實作介面的型別必須為每個元素提供具體內容。你在介面標記並構建可重用行為。介面可作參數或回傳值,有更多重用機會,因不同型別可實作相同介面。比起從基類衍生,開發人員更容易實作介面(譯註:不見得!)。
介面無法提供任何成員具體實作,也不能包含具體資料成員。你在定義合約,所有實作型別都應實現。
抽象基類可為衍生類提供具體實作,也描述共同行為。可詳細說明資料成員、具體方法、實作虛擬函式、屬性、事件、索引子。基類可只提供部分方法實作,給予部分可重用具體實作。抽象類別元素可為虛擬、抽象、非虛擬。抽象類別可為具體行為提供可行實作,介面不行。
在基類添加方法,所有衍生類自動隱式獲得此方法。基類提供有效方法隨時擴充衍生類行為:向基類添加並實作方法,所有衍生類立即具備。向介面添加方法,會破壞所有原先實作該介面的類。它們不包含新方法,無法通過編譯,所有實作者必須更新添加新方法。
System.Collections.CollectionBase 即混合模式:提供基類讓客戶建立 .NET 缺少的安全集合。已實作 IList、ICollection、IEnumerable。提供受保護方法 OnInsert()、OnInsertComplete() 讓你重載定義行為。IList 包含 Insert(),想提供自訂實作,可重載 CollectionBase 的虛擬方法處理事件:
public class IntList : System.Collections.CollectionBase
{
protected override void OnInsert(int index, object value) { /* 型別檢查 */ }
protected override void OnInsertComplete(int index, object value) { /* 記錄 */ }
}
public class MainProgram
{
public static void Main()
{
IntList l = new IntList();
IList il = l as IList;
il.Insert(0, 3);
il.Insert(0, "This is bad");
}
}