基于C#的接口基础教程之六
继承接口实现
接口具有不变性 但这并不意味着接口不再发展 类似于类的继承性 接口也可以继承和发展
注意 接口继承和类继承不同 首先 类继承不仅是说明继承 而且也是实现继承 而接口继承只是说明继承 也就是说 派生类可以继承基类的方法实现 而派生的接口只继承了父接口的成员方法说明 而没有继承父接口的实现 其次 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 但是没有改变从Control Paint 到IControl Paint 的映射 而通过类实例和接口实例调用Paint将会有下面的影响
Control c = new Control( ) ; TextBox t = new TextBox( ) ; IControl ic = c ; IControl it = t ; c Paint( ) ; // 影响Control Paint( ) ; t Paint( ) ; // 影响TextBox Paint( ) ; ic Paint( ) ; // 影响Control Paint( ) ; it Paint( ) ; // 影响Control Paint( ) ;
但是 当一个接口方法被映射到一个类中的虚拟方法 派生类就不可能覆盖这个虚拟方法并且改变接口的实现函数 例如 把上面的声明重新写为
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 ; c Paint( ) ; // 影响Control Paint( ); t Paint( ) ; // 影响TextBox Paint( ); ic Paint( ) ; // 影响Control Paint( ); it Paint( ) ; // 影响TextBox Paint( );
由于显式接口成员实现程序不能被声明为虚拟的 就不可能覆盖一个显式接口成员实现程序 一个显式接口成员实现程序调用另外一个方法是有效的 而另外的那个方法可以被声明为虚拟的以便让派生类可以覆盖它 例如:
interface IControl { void Paint( ) ; } class Control: IControl { void IControl Paint( ) { PaintControl( ); } protected virtual void PaintControl( ) { } } class TextBox: Control { protected override void PaintControl( ) { } }
这里 从Control 继承的类可以通过覆盖方法PaintControl 来对IControl Paint 的实现程序进行特殊化
重新实现接口
我们已经介绍过 派生类可以对基类中已经定义的成员方法进行重载 类似的概念引入到类对接口的实现中来 叫做接口的重实现(re implementation) 继承了接口实现的类可以对接口进行重实现 这个接口要求是在类定义的基类列表中出现过的 对接口的重实现也必须严格地遵守首次实现接口的规则 派生的接口映射不会对为接口的重实现所建立的接口映射产生任何影响
下面的代码给出了接口重实现的例子
interface IControl { void Paint( ) ; class Control: IControl void IControl Paint( ) {…} class MyControl: Control IControl public void Paint( ) {} }
实际上就是 Control把IControl Paint映射到了Control IControl Paint上 但这并不影响在MyControl中的重实现 在MyControl中的重实现中 IControl Paint被映射到MyControl Paint 之上
在接口的重实现时 继承而来的公有成员定义和继承而来的显式接口成员的定义参与到接口映射的过程
using System ; interface IMethods { void F( ) ; void G( ) ; void H( ) ; void I( ) ; } class Base: IMethods { void IMethods F( ) { } void IMethods G( ) { } public void H( ) { } public void I( ) { } } class Derived: Base IMethods { public void F( ) { } void IMethods H( ) { } }
这里 接口IMethods在Derived中的实现把接口方法映射到了Derived F Base IMethods G Derived IMethods H 还有Base I 前面我们说过 类在实现一个接口时 同时隐式地实现了该接口的所有父接口 同样 类在重实现一个接口时同时 隐式地重实现了该接口的所有父接口
using System ; interface IBase { void F( ) ; } interface IDerived: IBase { void G( ) ; } class C: IDerived { void IBase F( ) { //对F 进行实现的代码… } void IDerived G( ) { //对G 进行实现的代码… } } class D: C IDerived { public void F( ) { //对F 进行实现的代码… } public void G( ) { //对G 进行实现的代码… } }
lishixinzhi/Article/program/net/201311/15680