A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 杨占伟 中级黑马   /  2012-11-28 09:59  /  1191 人查看  /  2 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 杨占伟 于 2012-11-28 11:43 编辑

请详细举个接口的声明以及是如何应用的俱体的例子

2 个回复

倒序浏览
1、公有方法实现接口方法

尽管C#在定义接口时不用指明接口方法的访问控制方式,但默认接口方法均为public型(这可以从反编译的IL代码中看到)。下面是使用Reflector查看的接口IL代码
.class private interface abstract auto ansi IControl
{
   .method public hidebysig newslot abstract virtual instance void Paint() cil managed
   {
   }
}

实现接口的类需要实现所有接口方法。通常情况下,接口的实现方法也为public型。如下案例:
using System ;
interface IControl
{
   void Paint();
}
public class EditBox: IControl
{
   public void Paint()
   {
      Console.WriteLine("Pain method is called!");
   }
}
class Test
{
   static void Main()
   {
      EditBox editbox = new EditBox();
      editbox.Paint();
      ((IControl)editbox).Paint();
   }
}
程序的执行结果为:
Pain method is called!
Pain method is called!
接口就好像是关系型数据库中的一对多表,一个接口对应多个接口方法,每个接口方法又对应虚拟方法表(VMT)中的某个公有或私有方法


2、私有方法不能实现接口方法

如果想将接口方法直接实现为私有方法是办不到的。下面的EditBox的代码中Paint方法没有特殊说明,默认为private,导致代码无法执行:
using System ;
interface IControl
{
   void Paint();
}
public class EditBox: IControl
{
   void Paint()
   {
      Console.WriteLine("Pain method is called!");
   }
   public void ShowPaint()
   {
      this.Paint();
      ((IControl)this).Paint();
   }
}
class Test
{
   static void Main()
   {
      EditBox editbox = new EditBox();
      editbox.ShowPaint();
   }
}
程序在编译时将显示如下编译错误:““EditBox”不会实现接口成员“IControl.Paint()”。“EditBox.Paint()”或者是静态、非公共的,或者有错误的返回类型。”




这是由于接口规范中的方法默认的访问权限是public,而类中的默认访问权限是default,也就是说private,因此导致权限范围收缩,两者权限并不相同,所以必须将类的权限调整为public才可以使上面的代码得以执行。

3、实现专门的接口方法(1)

代码如下:
using System ;
interface IControl
{
   void Paint();
}
public class EditBox: IControl
{
   void Paint()
   {
      Console.WriteLine("Pain method is called!");
   }
   void IControl.Paint()
   {
      Console.WriteLine("IControl.Pain method is called!");
   }
   public void ShowPaint()
   {
      this.Paint();
      ((IControl)this).Paint();
   }
}
class Test
{
   static void Main()
   {
      EditBox editbox = new EditBox();
      editbox.ShowPaint();
      //editbox.Paint();
      ((IControl)editbox).Paint();
   }
}
EditBox类拥有一私有Paint方法,但这并不是接口方法的实现(上例已经分析过)。EditBox类中还包含了一“void IControl.Paint()”方法, 是该方法复写了接口的Paint方法,该方法是私有的(通过IL代码可以看出)。

注意:“void IControl.Paint()”前不能加任何的修饰限定符号,诸如public、private等,这在C#的语法中是不允许的。该方法反编译得到的IL代码如下:
.class public auto ansi beforefieldinit EditBox
      extends object
      implements IControl
{
      .......
      .method private hidebysig newslot virtual final instance void IControl.Paint() cil managed
      {
            .override IControl::Paint
      }
}



程序执行结果如下:
Pain method is called!
IControl.Pain method is called!
IControl.Pain method is called!
我们之所以可以通过((IControl)editbox).Paint()方法访问到代码是因为接口方法Paint是公有的。但是我们不能通过editbox.Paint()方法访问到代码是因为EditBox的Paint方法是私有的。 在EditBox内部,通过ShowPaint方法可以同时访问私有的Paint方法与接口IControl.Paint方法。

4、实现专门的接口方法(2)

如果EditBox中的Pait方法为公有并且同时提供了IControl.Paint方法,程序将是如何运行的呢?代码如下:
using System ;
interface IControl
{
   void Paint();
}
public class EditBox: IControl
{
   public void Paint()
   {
      Console.WriteLine("Pain method is called!");
   }
   void IControl.Paint()
   {
      Console.WriteLine("IControl.Pain method is called!");
   }
}
class Test
{
   static void Main()
   {
      EditBox editbox = new EditBox();
      editbox.Paint();
      ((IControl)editbox).Paint();
   }
}
程序执行结果如下:
Pain method is called!
IControl.Pain method is called!



可见,EditBox中公有的Paint方法并不是接口实现方法,真正的接口实现方法是IControl.Paint,这将导致editbox.Paint()方法与((IControl)editbox).Paint()的执行结果并不一样。

5、结论

接口方法的实现通常是通过类中的公有方法实现的;

在一些特殊情况下(代码隐藏、一个类实现的两个接口具有相同的接口方法等),需要专门实现某个接口的方法。
回复 使用道具 举报
非常感谢,学习了!
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马