[Attributes] [new | public | protected | internal | private] interface IReader [ : interface-base]
{
interface-method-declaration
interface-property-declaration
interface-event-declaration
interface-indexer-declaration
}
new修饰符只被允许在类(Class)的内部的接口使用,它表示这个接口成员隐藏了一个继承来的同名的成员函数。
一个接口可以继承自0到多个接口,这些接口被称作这个接口的显示基接口(explicit base interface)。
一个高开放度的接口不能继承一个比其开放程度低的接口,如一个被描述为public的接口不能继承一个被描述为internal的接口。
接口不能直接或者间接的继承自己。
在命名空间内的接口无法声明为 private、protected 或 protected internal,只能是internal或public,默认为internal
接口的继承是完全的传递闭包,即,接口继承所有基接口(base interface)的成员
接口的成员只能是方法,属性,事件,索引器,不能包含常数,字段,操作符,实例构造函数,析构函数,类型和任何静态成员。
接口的成员隐式声明为public,成员中包含任何修饰符都会产生编译错误。
在一个接口的声明中,不能有相同签名的方法,属性,事件,索引器。而可以与继承的接口中的成员有相同的签名,这不会引起错误,但是为产生一个警告,为了消除这个警告,可以显示的在重名的成员前加new关键字,来显示的隐藏基接口(base interface)中的成员。如果在没有重名的成员前加new关键字,也会出现警告。
接口成员的声明方式:
[Attributes] [new] return-type identifier ([formal-parameter-list]) ;
接口属性声明如下:
interface-property-declaration:
[attributes] [new] type identifier { interface-accessors }
interface-accessors:
[attributes] get ;
[attributes] set ;
[attributes] get ; [attributes] set ;
[attributes] set ; [attributes] get ;
接口事件声明如下:
[attributes] [new] event type identifier ;
接口索引器声明如下:
[attributes] [new] type this [ formal-parameter-list ] { interface-accessors }
接口成员的访问:
在单继承中,接口的使用和类(Class)一样,但是接口可以多继承,所以在接口多继承使用时,会出现继承自两个无关的接口,他们中有相同名字的成员,这时要显示的转换成相应的接口来调用,否则出现编译时错误。显示的转换不会产生运行时的代价。如果出现了new关键字隐藏基接口(base interface)中的成员,那么遵循以下规则:
如果一个成员从任意一条路径被隐藏,那么他在所有的路径都被隐藏,除非强制转换接口调用。
接口可以通过全限定名(fully qualified name)来使用。全限定名的使用方法为“接口名.成员名”,其中接口名必须是声明该成员的接口名,不能是派生的接口名。如果有命名空间,则再加上命名空间,如System.ICloneable.Clone
接口可以被类(Class)和结构(Struct)实现,实现接口的类(Class)和结构(Struct)隐式实现该接口所有的基接口(base interface)。类(Class)和结构(Struct)可以声明显示接口成员实现(explicit interface member implementations)。即,在类(Class)和结构(Struct)中实现的接口方法前,明确的带有接口的名称。以下把显示接口成员实现简写为EIMI。
全限定名的成员只能通过接口实例来访问。在显示实现接口成员时,任何访问修饰符都不允许的,以下修饰符也是不允许的:abstract, override,virtual,static
EIMI不能通过类(Class)和结构(Struct)的实例访问,它只能通过接口的实例访问。当类(Class)和结构(Struct)实现的接口不关心类(Class)和结构(Struct)如何被使用时,这个特点很有用。
EIMI可以使相同签名的接口成员不会混淆。如果不使用EIMI,类(Class)和结构(Struct)不允许实现相同签名和返回值的接口成员。
正确使用EIMI的方法是,类(Class)和结构(Struct)必须在基类(base class) 列表声明接口并在实现时以全限定名实现接口成员,并做到完全匹配接口成员的声明。
接口映射:
类(Class)和结构(Struct)必须实现列在基类(base class)列表上的所有接口成员。定位在类(Class)和结构(Struct)中实现的接口成员的过程叫做接口映射。
EIMI有更高的优先级做接口映射。
如果类(Class)和接口(Struct)实现了的接口中存在被隐藏的成员,那么这些成员必须通过EIMI来实现。
如果一个类(Class)实现了多个接口中有相同的基接口(base interface),那么只能有一个基接口(base interface)的成员实现。
基类的成员参与接口映射。
接口的继承:
接口的实现是可以继承的。
没有显示的重新实现接口,派生类不论如何也不可能改变接口的映射关系。
但是当接口被映射到一个类(Class)的虚方法(virtual method)时,派生类就可以重写虚方法来改变接口的实现映射。但是EIMI不能被声明为虚方法,所以不能重写EIMI。但是一个有效的方式是使用EIMI来调用其他方法。
接口的重实现:
一个继承了接口实现的类(Class),可以通过包含接口在基类(base class)列表上来重新实现该接口。
抽象类和接口:
抽象类(Abstract Class) 和 一般的类(Class) 一样,要实现列在基类(Base Class) 列表的所有接口的所有成员,但是,抽象类(Abstract Class) 可以映射这些成员到抽象(abstract)方法上。显示接口成员实现不能是抽象的,但是可以调用抽象类(Abstract Class)中的抽象(abstract)方法。