程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> 接口的實現(3)

接口的實現(3)

編輯:關於C語言

15.4.3 接口映射

類必須為在基類表中列出的所有接口的成員提供具體的實現。在類中定位接口成員的實現稱之為接口映射(interface mapping)。

映射,數學上表示一一對應的函數關系。接口映射的含義也是一樣,接口通過類來實現,那麼對於在接口中聲明的每一個成員,都應該對應著類的一個成員來為它提供具體的實現。

類的成員及其所映射的接口成員之間必須滿足下列條件:

●如果A和B都是成員方法,那麼A和B的名稱、類型、形參表(包括參數個數和每一個參數的類型)都應該是一致的。

●如果A和B都是屬性,那麼A和B的名稱、類型應當一致,而且A和B的訪問器也是類似的。但如果A不是顯式接口成員執行體,A允許增加自己的訪問器。

●如果A和B都是時間,那麼A和B的名稱、類型應當一致。

●如果A和B都是索引指示器,那麼A和B的類型、形參表(包括參數個數和每一個參數的類型)應當一致。而且A和B的訪問器也是類似的。但如果A不是顯式接口成員執行體,A允許增加自己的訪問器。

那麼,對於一個接口成員,怎樣確定由哪一個類的成員來實現呢?即一個接口成員映射的是哪一個類的成員?在這裡我們敘述一下接口映射的過程。假設類C實現了一個接口IInterface,Member是接口IIterface中的一個成員。在定位由誰來實現接口成員Member,即Member的映射過程是這樣的:

(1)如果C中存在著一個顯式接口成員執行體,該執行體與接口IInterface及其成員Member相對應,則由它來實現Member成員。

(2)如果條件(1)不滿足,且C中存在著一個非靜態的公有成員,該成員與接口成員Member相對應,則由它來實現Member成員。

(3)如果上述條件仍不滿足,則在類C聲明的基類列表中尋找一個C的基類D,用D來代替C。

(4)重復步驟(1)---(3),遍歷C的所有直接基類和非直接基類,直到找到一個滿足條件的類的成員。

(5)如果仍然沒有找到,則報告錯誤。

下面是一個調用基類方法來實現接口成員的例子。類Class2實現了接口Interface1,類Class2的基類Class1的成員也參與了接口的映射,也就是說,類Class2在對接口Interface1進行實現時,使用了類Class1提供的成員方法F來實現接口Interface1的成員方法F:

interface Interface1
{
 void F();
}
class Class1
{
 public void F(){}
 public void G(){}
}
class Class2:Class1,Interface1
{
 new public void G(){}
}

注意:接口的成員包括它自己聲明的成員,而且包括該接口所有父接口聲明的成員。在接口映射時,不僅要對接口聲明體中顯式聲明的所有成員進行映射,而且要對隱式地從父接口那裡繼承來的所有接口成員進行映射。

在進行接口映射時,還要注意下面兩點:

●在決定由類中的哪個成員來實現接口成員時,類中顯式說明的接口成員比其它成員優先實現。

●使用private,protected和static修飾符的成員不能參與實現接口映射。

例如:

interface ICloneable
{
 object Clone();
}
class C:ICloneable
{
 object ICloneable.Clone(){...}
 public object Clone(){...}
}

例子中成員ICloneable.Clone稱為接口ICloneable的成員Clone的實現者,因為它是顯式說明的接口成員,比其它成員有著更高的優先權。

如果一個類實現了兩個或兩個以上名字、類型和參數類型都相同的接口,那麼類中的一個成員就可能實現所有這些接口成員:

interface IControl
{
 void Paint();
}
interface IForm
{
 void Paint();
}
class Page:IControl,IForm
{
 public void Paint(){...}
}

這裡,接口IControl和IForm的方法Paint都映射到了類Page中的Paint方法。當然也可以分別用顯式的接口成員分別實現這兩個方法:

interface IControl
{
 void Paint();
}
interface IForm
{
 void Paint();
}
class Page:IControl,IForm
{
 public void IControl.Paint(){
   //具體的接口實現代碼
}
 public void IForm.Paint(){
  //具體的接口實現代碼
 }
}

上面的兩種寫法都是正確的。但是如果接口成員在繼承中覆蓋了父接口的成員,那麼對該接口成員的實現就可能必須映射到顯式接口成員執行體。看下面的例子:

interface IBase
{
 int P {get;}
}
interface IDerived:IBase
{
 new int p();
}
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved