熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> .NET編程 >> 正文

基於C#的接口基礎教程之五

2022-06-13   來源: .NET編程 

  第五節實現接口

  顯式實現接口成員

  為了實現接口類可以定義顯式接口成員執行體(Explicit interface member implementations)顯式接口成員執行體可以是一個方法一個屬性一個事件或者是一個索引指示器的定義定義與該成員對應的全權名應保持一致

  using System ;
  interface ICloneable
  {
   object Clone( ) ;
  }
  interface IComparable
  {
   int CompareTo(object other) ;
  }
  class ListEntry: ICloneable IComparable
  {
   object ICloneableClone( ) {…}
   int IComparableCompareTo(object other) {…}
  }

  上面的代碼中ICloneableClone 和IComparableCompareTo 就是顯式接口成員執行體

  說明

  不能在方法調用屬性訪問以及索引指示器訪問中通過全權名訪問顯式接口成員執行體事實上顯式接口成員執行體只能通過接口的實例僅僅引用接口的成員名稱來訪問

  顯式接口成員執行體不能使用任何訪問限制符也不能加上abstract virtual override或static 修飾符

  顯式接口成員執行體和其他成員有著不同的訪問方式因為不能在方法調用屬性訪問以及索引指示器訪問中通過全權名訪問顯式接口成員執行體在某種意義上是私有的但它們又可以通過接口的實例訪問也具有一定的公有性質

  只有類在定義時把接口名寫在了基類列表中而且類中定義的全權名類型和返回類型都與顯式接口成員執行體完全一致時顯式接口成員執行體才是有效的例如

  class Shape: ICloneable
  {
   object ICloneableClone( ) {…}
   int IComparableCompareTo(object other) {…}
  }
  使用顯式接口成員執行體通常有兩個目的

  因為顯式接口成員執行體不能通過類的實例進行訪問這就可以從公有接口中把接口的實現部分單獨分離開如果一個類只在內部使用該接口而類的使用者不會直接使用到該接口這種顯式接口成員執行體就可以起到作用

  顯式接口成員執行體避免了接口成員之間因為同名而發生混淆如果一個類希望對名稱和返回類型相同的接口成員采用不同的實現方式這就必須要使用到顯式接口成員執行體如果沒有顯式接口成員執行體那麼對於名稱和返回類型不同的接口成員類也無法進行實現

  下面的定義是無效的因為Shape 定義時基類列表中沒有出現接口IComparable

  class Shape: ICloneable
  {
   object ICloneableClone( ) {…}
  }
  class Ellipse: Shape
  {
   object ICloneableClone( ) {…}
  }

  在Ellipse 中定義ICloneableClone是錯誤的因為Ellipse即使隱式地實現了接口ICloneableICloneable仍然沒有顯式地出現在Ellipse定義的基類列表中

  接口成員的全權名必須對應在接口中定義的成員如下面的例子中Paint的顯式接口成員執行體必須寫成IControlPaint

  using System ;
  interface IControl
  {
   void Paint( ) ;
  }
  interface ITextBox: IControl
  {
   void SetText(string text) ;
  }
  class TextBox: ITextBox
  {
   void IControlPaint( ) {…}
   void ITextBoxSetText(string text) {…}
  }

  實現接口的類可以顯式實現該接口的成員當顯式實現某成員時不能通過類實例訪問該成員而只能通過該接口的實例訪問該成員顯式接口實現還允許程序員繼承共享相同成員名的兩個接口並為每個接口成員提供一個單獨的實現

  下面例子中同時以公制單位和英制單位顯示框的尺寸Box類繼承 IEnglishDimensions和 IMetricDimensions兩個接口它們表示不同的度量衡系統兩個接口有相同的成員名 Length 和 Width

  程序清單 DemonInterfacecs

  interface IEnglishDimensions
  {
   float Length ( ) ;
   float Width ( ) ;
  }
  interface IMetricDimensions
  {
   float Length ( ) ;
   float Width ( ) ;
  }
  class Box : IEnglishDimensions IMetricDimensions
  {
   float lengthInches ;
   float widthInches ;
   public Box(float length float width)
   {
    lengthInches = length ;
    widthInches = width ;
   }
   float IEnglishDimensionsLength( )
   {
    return lengthInches ;
   }
   float IEnglishDimensionsWidth( )
   {
    return widthInches ;
   }
   float IMetricDimensionsLength( )
   {
    return lengthInches * f ;
   }
   float IMetricDimensionsWidth( ) 
   {
    return widthInches * f ;
   }
   public static void Main( )
   {
    //定義一個實類對象 myBox:
    Box myBox = new Box(f f);
    // 定義一個接口 eDimensions::
    IEnglishDimensions eDimensions = (IEnglishDimensions) myBox;
    IMetricDimensions mDimensions = (IMetricDimensions) myBox;
    // 輸出:
    SystemConsoleWriteLine( Length(in): {} eDimensionsLength( ));
    SystemConsoleWriteLine( Width (in): {} eDimensionsWidth( ));
    SystemConsoleWriteLine( Length(cm): {} mDimensionsLength( ));
    SystemConsoleWriteLine( Width (cm): {} mDimensionsWidth( ));
   }
  }

  輸出Length(in): Width (in): Length(cm): Width (cm):

  代碼討論如果希望默認度量采用英制單位請正常實現 Length 和 Width 這兩個方法並從 IMetricDimensions 接口顯式實現 Length 和 Width 方法

  public float Length( )
  {
   return lengthInches ;
  }
  public float Width( )
  {
   return widthInches;
  }
  float IMetricDimensionsLength( )
  {
   return lengthInches * f ;
  }
  float IMetricDimensionsWidth( )
  {
   return widthInches * f ;
  }

  這種情況下可以從類實例訪問英制單位而從接口實例訪問公制單位

  SystemConsoleWriteLine(Length(in): {} myBoxLength( )) ;
  SystemConsoleWriteLine(Width (in): {} myBoxWidth( )) ;
  SystemConsoleWriteLine(Length(cm): {} mDimensionsLength( )) ;
  SystemConsoleWriteLine(Width (cm): {} mDimensionsWidth( )) ;


From:http://tw.wingwit.com/Article/program/net/201311/15704.html
    推薦文章
    Copyright © 2005-2022 電腦知識網 Computer Knowledge   All rights reserved.