程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> Effective C#原則19:選擇定義和實現接口而不是繼承(1)

Effective C#原則19:選擇定義和實現接口而不是繼承(1)

編輯:關於C語言

抽象類在類的繼承中提供了一個常規的“祖先”。一個接口描述 了一個可以被其它類型實現的原子級泛型功能。各有千秋,卻也不盡相同。接口 是一種合約式設計:一個類型實現了某個接口的類型,就必須實現某些期望的方 法。抽象類則是為一個相關類的集合提供常規的抽象方法。這些都是老套的東西 了:它是這樣的,繼承就是說它是某物(is a,),而接口就是說它有某個功能 (behaves like.)! 這些陳詞濫調已經說了好久了,因為它們提供了說明,同時 在兩個結構上描述它們的不同:基類是描述對象是什麼,接口描述對象有某種行為。

接口描述了一組功能集合,或者是一個合約。你可以在接口裡創建 任何的占位元素(placeholder,譯注:就是指先定義,後面再實現的一些內容) :方法,屬性,索引器以及事件。任何實現類型這個接口的類型必須為接口裡的 每個元素提供具體的內容。你必須實現所有的方法,提供全部屬性訪問器,索引 器,以及定義接口裡的所有事件。你在接口裡標記並且構造了可重用的行為。你 可以把接口當成參數或者返回值,你也可以有更多的機會重用代碼,因為不同的 類型可以實現相同的接口。更多的是,比起從你創建的基類派生,開發人員可以 更容易的實現接口。(譯注:不見得!)

你不能在接口裡提供任何成員的具 體實現,無論是什麼,接口裡面都不能實現。並且接口也不能包含任何具體的數 據成員。你是在定義一個合約,所有實現接口的類型都應該實現的合約。

抽象的基類可以為派生類提供一些具體的實現,另外也描述了一些公共 的行為。你可以更詳細的說明數據成員,具體方法,實現虛函數,屬性,事件以 及索引器。一個基類可以只提供部份方法的實現,從而只提供一些公共的可重用 的具體實現。抽象類的元素可以是虛的,抽象的,或者是非虛的。一個抽象類可 以為具體的行為提供一個可行的實現,而接口則不行。

重用這些實現還 有另一個好處:如果你在基類中添加一個方法,所有派生類會自動隱式的增加了 這個方法。這就是說,基類提供了一個有效的方法,可以隨時擴展幾個(派生)類 型的行為:就是向基類添加並實現方法,所有派生類會立即具有這些行為。而向 一個接口添加一個方法,所會破壞所有原先實現了這個接口的類。這些類不會包 含新的方法,而且再也通不過編譯。所有的實現者都必須更新,要添加新的方法 。

這兩個模式可以混合並重用一些實現代碼,同時還可以實現多個接口 。System.Collections.CollectionBase就是這樣的一個例子,它個類提供了一 個基類。你可以用這個基類你的客戶提供一些.Net缺少的安全集合。例如,它已 經為你實現了幾個接口:IList, ICollection,和IEnumerable。另外,它提供了 一個受保護的方法,你可以重載它,從而為不同的使用情況提供自己定義的行為 。IList接口包含向集合中添加新對象的Insert()方法。想自己更好的提供一個 Insert方法的實現,你可以通過重載CollectionBase類的OnInsert()或 OnInsertCcomplete()虛方法來處理這些事件:

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.ToString(), value.ToString());
     Console.WriteLine( "List Contains {0} items",
     this.List.Count.ToString());
  }
  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.ToString( ), value.ToString( ));
   Console.WriteLine( "List Contains {0} items",
    this.List.Count.ToString( ) );
 }
}
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" );
 }
}

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved