接口

接口

接口允许包含方法、属性、索引器和事件的签名,这里只允许包含签名,而不能包含实现(但在C#8.0中可以有方法的[默认实现][2]),接口不能包含常量、字段、运算符、实例构造函数、析构函数以及任何静态成员。

接口特点:

  • 接口可以从一个或多个基接口继承(或叫实现),一个类或者结构可以实现多个接口
  • 接口只允许包含方法、属性、索引器和事件的签名,这里只允许包含签名,而不能包含实现(在C#7语法中可以有实现)
  • 接口不能包含常量、字段、运算符、实例构造函数、析构函数以及任何静态成员
  • 接口的成员默认是公共的(public),且不可以再显式声明为public,否则将产生编译异常
  • 接口不能被实例化,接口的声明是抽象的(底层实现上)
  • 实现接口的类必须实现接口的所有成员,不管是方法、属性、索引器还是事件

定义接口

接口的访问修饰符(默认为internal),可用public,但对于接口的成员,不能使用访问修饰符(默认public),但不能写出来。接口也支持parital进行分部处理。

// 默认internal, 可显式地设定为public和internal
interface Sample
{
    // 默认public,但不能显式地设置访问修饰符
    void SayHello(); //方法
    void SayYes() { Console.WriteLine(“Yes”); } //(C#8.0)方法默认实现,无;结尾
    int Age { get; set; } //属性
    EventHandler SizeChanged(); //事件
    int this[int index] { get; set; } //索引器
}

接口类型的变量可以指向任何实现了这个接口的类的实例,这样可以灵活地指定某个实现类,而不需要改变依赖这个接口的代码,如此只能通过这些接口类型的引用调用接口的方法,如果想要调用某个实现类中自定义的、不在接口中的方法,就需要把引用强制转换为合适的类型。

基类中的实现作为接口实现

interface ISample
{
    void Method1();
}

class ClassOne
{
    public void Method1() { Console.WriteLine("ClassOne ISample"); }
}

class ClassTwo : ClassOne, ISample
{}

其中ClassTwo并未显式实现ISample接口中的Method1方法,但它通过继承ClassOne,ClassOne中实现了该方法

实现多个接口

当一个类实现多个接口时,实现类中要实现所有实现的接口规定的所有成员,可以使用它实现的任意接口类型来引用它的实例,但使用不同的接口类型引用,直接影响该类型的可用成员。

实现具有相同成员的接口,类可以实现多个接口,有可能在两个或更多的接口中出现具有相同签名的成员,可以提供一种实现,以供所有定义了该成员的接口共享,也可以显式地定义接口成员实现。

interface ITest1
{
    void Method1();
}
interface ITest2
{
    void Method1();
}
class ClassOne : ITest1, ITest2
{
    //ITest1和ITest2的共同实现
    public void Method1()
    {
    }
}
class ClassTwo : ITest1, ITest2
{
    //显式地定义接口成员实现
    public void ITest1.Method1()
    {
    }
    public void ITest2.Method1()
    {
    }

    public void NewMethod()
    {
      //Method1(); //编译错误
      //this.Method1(); //编译错误
      ((ITest1)this).Method1(); //通过接口访问
      //显式地定义接口成员实现的方法,实现类和其派生类都无法访问显式的接口成员实现,只能通过接口进行调用
}

参考引用

[1]: C# 权威指南
[2]: [默认实现](https://github.com/dotnet/csharplang/blob/master/proposals/default-interface-methods.md “默认实现”)

posted @ 2019-06-03 09:11  Allen2015  阅读(207)  评论(0编辑  收藏  举报