原贴地址: http://www.cnblogs.com/dudu837/archive/2009/12/07/1618663.html

 

在实现接口的时候,VS提供了两个菜单,一个是"实现接口",一个是"显式实现接口",它们到底有何不一样呢

我们来比较一下看看

1.首先假设我们有一个接口

public interface ICustomer
{
    void SomeMethod();//接口的所有成员都暗自成为abstract,我们不能为它提供缺省实现,无论这份实现是 多么平淡无奇;接口的成员也都暗自成为public,我们不能以关键字abstract或 public来修改(修饰)其中某个成员。
}

2.如果是"实现接口",那么代码大致如下

public class Customer:ICustomer
{

    #region ICustomer 成员

    public void SomeMethod()
    {
        throw new NotImplementedException();
    }

    #endregion
}

3.如果是"显式实现接口",那么代码大致如下

public class Customer:ICustomer
{

    #region ICustomer 成员

    void ICustomer.SomeMethod()//显示接口成员的访问级别暗中是public,不允许程序员再加任何修饰符
    {
        throw new NotImplementedException();
    }

    #endregion
}

大家看到差别了吧?显式实现的方式,那些方法都会加上一个前缀的。但是,这到底意味着什么呢?

如果是实现接口

public class DAL {
    /// <summary>
    /// 如果我们是直接实现接口的话,那么既可以用接口调用方法,也可以用具体类调用方法
    /// </summary>
    public void GetCustomer() {
        Customer customer = new Customer();
        customer.SomeMethod();
    }

    public void GetCustomer2() {
        ICustomer customer = new Customer();
        customer.SomeMethod();
    }
}

如果是显式实现接口

public class DAL {
    /// <summary>
    /// 如果我们是显式实现接口的话,那么要访问里面的方法就只能是通过接口来调用,而不能通过具体类来做
    /// </summary>
    public void GetCustomer() {
        ICustomer customer = new Customer();
        customer.SomeMethod();
    }
}

此外,我们还可以在继承接口的类中同时提供实现接口和显式实现接口两种方式,这样就完成了对一个接口成员提供多份实现实体,访问时可以用类的实例和接口的引用来分别调用这两种实现实体。

现在大部分的系统为了保证扩展性,都广泛地使用接口。显式实现接口,可以隐藏具体类的复杂性。

 

1.隐式实现的接口

[c-sharp] view plaincopy
  1. interface IControl  
  2.  {  
  3.      void Paint();  
  4.  }  
  5.  public class EditBox : IControl  
  6.  {  
  7.      public void Paint()  
  8.      {  
  9.          Console.WriteLine("Pain method is called!");  
  10.     }  
  11. }  
  12. class Test  
  13. {  
  14.     static void Main()  
  15.     {  
  16.         EditBox editbox = new EditBox();  
  17.         editbox.Paint();  
  18.         ((IControl)editbox).Paint();  
  19.         Console.ReadKey();  
  20.     }  
  21. }  

 

结果:

Pain method is called!
Pain method is called!


说明:从实例中我们可以看到用隐式实现的接口既可以通过类来访问,也可以通过接口来访问!

 

2.显式实现的接口

[c-sharp] view plaincopy
  1. interface IControl  
  2.  {  
  3.      void Paint();  
  4.  }  
  5.  public class EditBox : IControl  
  6.  {  
  7.      void IControl.Paint()  
  8.      {  
  9.          Console.WriteLine("IControl.Pain method is called!");  
  10.     }  
  11. }  
  12. class Test  
  13. {  
  14.     static void Main()  
  15.     {  
  16.         EditBox editbox = new EditBox();  
  17.         //editbox.Paint();//通过类访问会出错  
  18.         ((IControl)editbox).Paint();  
  19.         Console.ReadKey();  
  20.     }  
  21. }  

 

结果:

1IControl.Pain method is called!


说明:从实例中我们可以看到用显式实现的接口只能通过接口来访问,如果试图通过类来访问会出错:““ConsoleApplication1.EditBox”并不包含“Paint”的定义。”

3.同时用显/隐式实现接口会怎么样?

[c-sharp] view plaincopy
  1. interface IControl  
  2.  {  
  3.      void Paint();  
  4.  }  
  5.  public class EditBox : IControl  
  6.  {  
  7.      void IControl.Paint()  
  8.      {  
  9.          Console.WriteLine("IControl.Pain method is called!");  
  10.     }  
  11.     public void Paint()  
  12.     {  
  13.         Console.WriteLine("Pain method is called!");  
  14.     }  
  15. }  
  16. class Test  
  17. {  
  18.     static void Main()  
  19.     {  
  20.         EditBox editbox = new EditBox();  
  21.         editbox.Paint();  
  22.         ((IControl)editbox).Paint();  
  23.         Console.ReadKey();  
  24.     }  
  25. }  

 

结果:

Pain method is called!
IControl.Pain method is called!


说明:当同时用显/隐式实现接口时,显式才是真正的接口实现方法!

4.结论

在 多数情况下,我们都是用隐式来实现接口,此时既可以通过类来访问,又可以通过接口来访问,而通过显式实现的接口则只能通过接口来访问,总结一下就是:当显 式实现方式存在时,隐式实现方式就失效了。但这不能表示显式实现方式就不好,当一个类实现的多个接口中具有相同的方法时,用显式方式来专门实现某个接口的 方法时就显得非常有用!