CLR via C#学习笔记-第十三章-定义接口、继承接口

13.1 类和接口继承

接口是为了实现多继承

所有的类都继承了System.Object,及其四个公共实例方法:ToString、Equals、GetHashCode、GetType。

CLR允许定义接口,它实际只是对一组方法签名进行了统一命名。这些方法不提供任何实现。

类通过指定接口名称来继承接口,而且必须显式实现接口方法,否则CLR认为此类型定义无效。

实现接口方法的过程比较繁琐,所以说接口继承是实现多继承的一种缩水版机制。

编译器和CLR允许一个类继承多个接口,继承的所有接口都必须实现。

接口继承特点

类继承的一个重要特点是,凡是能使用基类型实例的地方,都能使用派生类型的实例。

类似的,凡是能够使用具名接口类型的实例的地方,都能使用实现了接口的一个类型的实例。

13.2 定义接口

接口还能定义事件、无参属性和有参属性。

所有这些东西的本质上都是方法,他们只是语法上的简化。

不过接口不能定义任何构造器方法,也不能定义任何实例字段。

接口不能定义静态成员

CLR允许接口定义静态方法、字段、常量和构造器,但符合CLS标准的接口决不允许,C#禁止接口定义任何一种静态成员。

接口定义就是类型定义

在CLR看来,接口定义就是类型定义。

也就是说CLR会为接口类型对象定义内部数据结构,同时可通过反射机制来查询接口类型的功能。

和类型一样,接口可在文件范围中定义,也可嵌套在另一个类型中。定义接口类型时可指定你希望的任何可见性、可访问性。

接口继承不是严格的继承

接口定义可以从另一个或多个接口继承。但它不是严格的继承。

接口继承的工作方式并不完全和类继承一样。

作者倾向于将接口结成看成是将其他接口的协定contract包括到2新接口中。

例如ICollection<T>接口定义包含了IEnumerable<T>和IEnumerable两个接口的协定,有下面两层含义:

1.继承ICollection<T>接口的任何类必须实现ICollection<T>、IEnumerable<T>和IEnumerable三个接口所定义的方法。

2.任何代码在引用实现ICollection<T>接口的对象时,该类型还实现了IEnumerable<T>和IEnumerable接口。

13.3 继承接口

显式为实现接口的方法标记virtual和隐式的区别

编译器要求将实现接口的方法标记为public。

CLR要求将接口方法标记为virtual,编译器会将他们标记为virtual和sealed。这会阻止派生类重写接口方法。

将方法显式标记为virtual,编译器就会将该方法标记为virtual并保持它的非密封状态,使派生类能重写它。

派生类重写基类实现的接口方法

派生类不能重写sealed的接口方法,但派生类可重新继承同一个接口,并为接口方法提供自己的实现。

下例对此进行了演示:

//派生自Object,他实现了IDisposable
internal class Base:IDisposable{
    public void Dispose(){
        Console.WriteLine("Base's Dispose");
    }
}
//重新实现了IDisposable
internal class Derived:Base,IDisposable{
    new public void Dispose(){
        Console.WriteLine("Base's Dispose");
    }
}

在Main函数中进行调用:

/*****************第一个例子****************/
Base b=new Base();
//用b的类型调用Dispose,显示"Base's Dispose"
b.Dispose();
//用b的对象的类型调用Dispose,显示"Base's Dispose"
((IDisposable)b).Dispose();

/*****************第二个例子****************/
Derived d=new Derived();
//用d的类型调用Dispose,显示"Derived's Dispose"
d.Dispose();
//用d的对象的类型调用Dispose,显示"Derived's Dispose"
((IDisposable)d).Dispose();

/*****************第三个例子****************/
b=new Derived();
//用b的类型调用Dispose,显示"Base's Dispose"
b.Dispose();
//用b的对象的类型调用Dispose,显示"Derived's Dispose"
((IDisposable)b).Dispose();
原文地址:https://www.cnblogs.com/errornull/p/9905469.html