接 口

CLR不支持多继承(因而所有托管编程语言也不支持)。CLR只是通过接口提供了"缩水版"的多继承。

 

接口可以定义事件、无参属性、索引器,这些东西本质上都是方法,它们只是对语法的一种简化而已。接口不能定义构造器方法,不能定义实例字段。虽然CLR允许接口定义静态方法、静态字段、常量、静态构造器,但C#禁止接口定义这些静态成员。

 

对于一个接口方法(类继承接口所实现的方法)C#编译器要求接口方法标记为public,CLR要求接口方法标记为virtual(这样派生类可以重写该方法,如果没有显示标记virtual,将默认标记为virtual sealed(派生类将不能重写该方法))。

 

隐式接口方法和显示接口方法的实现

看以下代码:

internal class SimpleType:IDisposable

{

    public void Dispose(){ Console.WriteLine("Dispose");}

}

以上看似只有一个方法(确实只有一个方法,呵呵),该方法是一个隐式接口方法。但在该类加载到CLR时,该类的方法表里指向这个方法的记录项却又两个,一个是接口方法的记录项,一个是新方法的记录项(因为这个方法的签名与IDisposable接口定义的Dispose()方法完全一致,且可访问性是public)

public class Program{

    public static void Main(){

        SimpleType st=new SimpleType();

        st.Dispose();         //Dispose

        IDisposable d=st;

        d.Dispose();          //Dispose

    }

}

看以上代码, st.Dispose()和d.Dispose()都指向同一个隐式接口方法

如果将SimpleType类写成如下:

internal class SimpleType:IDisposable

{

    public void Dispose(){ Console.WriteLine("Dispose");}

    void IDisposable.Dispose(){Console.WriteLine("IDispose");}

}

运行Main()方法的结果将是:

Dispose

IDispose

其中void IDisposable.Dispose(){Console.WriteLine("IDispose");}是显示接口方法,这样接口方法的记录项会指向该显示接口方法,而新方法的记录项会指向 public void Dispose(){ Console.WriteLine("Dispose");}

在C#中将定义方法的那个接口的名称作为方法名的前缀(如这里的 IDisposable.Dispose)称为显示接口方法实现(EIMI)。定义EIMI时不能指定可访问性,默认是private。要调用EIMI时只能通过接口类型的一个变量来进行。另外,EIMI不能标记为virtual,所以它不能被重写。

 

泛型接口有一个好处是类可以实现同一个接口若干次,只要每次使用不同的类型参数:

//该类实现了IComparable<T>接口两次

public class Number:IComparable<Int32>,IComparable<String>

{

    private Int32 m_val=5;

    public Int32 CompareTo(Int32 n)

    {

        return m_val.CompareTo(n);

    }

    public Int32 CompareTo(string s)

    {

       return m_val.CompareTo(Int32.Parse(s));

    }

}

 

定义实现多个接口的一个类型时,这些接口有可能定义了具有相同名称和签名(返回值及参数)的方法:

public interface IWindow{

   Object GetMenu();

}

public interface IRestaurant{

   Object GetMenu();

}

要定义一个实现了以上俩接口的类型,必须用 显示接口方法实现:

public class MarioPizzeria:IWindow,IRestaurant

{   //这是IWindow的GetMenu()方法实现

    Object IWindow.GetMenu(){...}

    //这是IRestaurant的GetMenu()方法实现

    Object IRestaurant.GetMenu(){...}

    //这个GetMenu()方法是可选的,与接口无关

    public Object GetMenu(){...}

}

 

 

 

未完待续...

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值