继承接口实现
接口具有不变性但这并不意味着接口不再发展类似于类的继承性接口也可以继承和发展
注意接口继承和类继承不同首先类继承不仅是说明继承而且也是实现继承而接口继承只是说明继承也就是说派生类可以继承基类的方法实现而派生的接口只继承了父接口的成员方法说明而没有继承父接口的实现其次C#中类继承只允许单继承但是接口继承允许多继承一个子接口可以有多个父接口
接口可以从零或多个接口中继承从多个接口中继承时用:后跟被继承的接口名字多个接口名之间用分割被继承的接口应该是可以访问得到的比如从private 类型或internal 类型的接口中继承就是不允许的接口不允许直接或间接地从自身继承和类的继承相似接口的继承也形成接口之间的层次结构
请看下面的例子
using System ;
interface IControl
{
void Paint( ) ;
}
interface ITextBox: IControl
{
void SetText(string text) ;
}
interface IListBox: IControl
{
void SetItems(string[] items) ;
}
interface IComboBox: ITextBox IListBox { }
对一个接口的继承也就继承了接口的所有成员上面的例子中接口ITextBox和IListBox都从接口IControl中继承也就继承了接口IControl的Paint方法接口IComboBox从接口ITextBox和IListBox中继承因此它应该继承了接口ITextBox的SetText方法和IListBox的SetItems方法还有IControl的Paint方法
一个类继承了所有被它的基本类提供的接口实现程序
不通过显式的实现一个接口一个派生类不能用任何方法改变它从它的基本类继承的接口映射例如在声明中
interface IControl
{
void Paint( );
}
class Control: IControl
{
public void Paint( ) {}
}
class TextBox: Control
{
new public void Paint( ) {}
}
TextBox 中的方法Paint 隐藏了Control中的方法Paint 但是没有改变从ControlPaint 到IControlPaint 的映射而通过类实例和接口实例调用Paint将会有下面的影响
Control c = new Control( ) ;
TextBox t = new TextBox( ) ;
IControl ic = c ;
IControl it = t ;
cPaint( ) ; // 影响ControlPaint( ) ;
tPaint( ) ; // 影响TextBoxPaint( ) ;
icPaint( ) ; // 影响ControlPaint( ) ;
itPaint( ) ; // 影响ControlPaint( ) ;
但是当一个接口方法被映射到一个类中的虚拟方法派生类就不可能覆盖这个虚拟方法并且改变接口的实现函数例如把上面的声明重新写为
interface IControl
{
void Paint( ) ;
}
class Control: IControl
{
public virtual void Paint( ) {}
}
class TextBox: Control
{
public override void Paint( ) {}
}
就会看到下面的结果
Control c = new Control( ) ;
TextBox t = new TextBox( ) ;
IControl ic = c ;
IControl it = t ;
cPaint( ) ; // 影响ControlPaint( );
tPaint( ) ; // 影响TextBoxPaint( );
icPaint( ) ; // 影响ControlPaint( );
itPaint( ) ; // 影响TextBoxPaint( );
由于显式接口成员实现程序不能被声明为虚拟的就不可能覆盖一个显式接口成员实现程序一个显式接口成员实现程序调用另外一个方法是有效的而另外的那个方法可以被声明为虚拟的以便让派生类可以覆盖它例如:
interface IControl
{
void Paint( ) ;
}
class Control: IControl
{
void IControlPaint( ) { PaintControl( ); }
protected virtual void PaintControl( ) {}
}
class TextBox: Control
{
protected override void PaintControl( ) {}
}
这里从Control 继承的类可以通过覆盖方法PaintControl 来对IControlPaint 的实现程序进行特殊化
重新实现接口
我们已经介绍过派生类可以对基类中已经定义的成员方法进行重载类似的概念引入到类对接口的实现中来叫做接口的重实现(reimplementation)继承了接口实现的类可以对接口进行重实现这个接口要求是在类定义的基类列表中出现过的对接口的重实现也必须严格地遵守首次实现接口的规则派生的接口映射不会对为接口的重实现所建立的接口映射产生任何影响
下面的代码给出了接口重实现的例子
interface IControl
{
void Paint( ) ;
class Control: IControl
void IControlPaint( ) {…}
class MyControl: Control IControl
public void Paint( ) {}
}
实际上就是Control把IControlPaint映射到了ControlIControlPaint上但这并不影响在MyControl中的重实现在MyControl中的重实现中IControlPaint被映射到MyControlPaint 之上
在接口的重实现时继承而来的公有成员定义和继承而来的显式接口成员的定义参与到接口映射的过程
using System ;
interface IMethods
{
void F( ) ;
void G( ) ;
void H( ) ;
void I( ) ;
}
class Base: IMethods
{
void IMethodsF( ) { }
void IMethodsG( ) { }
public void H( ) { }
public void I( ) { }
}
class Derived: Base IMethods
{
public void F( ) { }
void IMethodsH( ) { }
}
这里接口IMethods在Derived中的实现把接口方法映射到了DerivedFBaseIMethodsG DerivedIMethodsH 还有BaseI前面我们说过类在实现一个接口时同时隐式地实现了该接口的所有父接口同样类在重实现一个接口时同时隐式地重实现了该接口的所有父接口
using System ;
interface IBase
{
void F( ) ;
}
interface IDerived: IBase
{
void G( ) ;
}
class C: IDerived
{
void IBaseF( )
{
//对F 进行实现的代码…
}
void IDerivedG( )
{
//对G 进行实现的代码…
}
}
class D: C IDerived
{
public void F( )
{
//对F 进行实现的代码…
}
public void G( )
{
//对G 进行实现的代码…
}
}
这里对IDerived的重实现也同样实现了对IBase的重实现把IBaseF 映射到了DF