正文

C#语法详细解释---接口[6]2008-09-17 01:52:00

【评论】 【打印】 【字体: 】 本文链接:http://blog.pfan.cn/yzrj/37346.html

分享到:

interface IListBox: IControl
{
void SetItems(string[] items);
}

class ComboBox: IControl, ITextBox, IListBox
{
void IControl.Paint() {...}

void ITextBox.SetText(string text) {...}

void IListBox.SetItems(string[] items) {...}
}

在基类列表中命名的 IControl、由 ITextBox 继承的 IControl 和由 IListBox 继承的 IControl 不可能有各自不同的实现。事实上,没有为这些接口提供单独实现的打算。相反ITextBox IListBox 的实现共享相同的 IControl 的实现因而可以简单地认为 ComboBox 实现了三个接口IControlITextBox IListBox

基类的成员参与接口映射。在下面的示例中

interface Interface1
{
void F();
}

class Class1
{
public void F() {}

public void G() {}
}

class Class2: Class1, Interface1
{
new public void G() {}
}

Class1 中的方法 F 用于 Class2 Interface1 的实现中。

1.1.1 接口实现继承

类继承由其基类提供的所有接口实现。

如果不显式地重新实现 (re-implementing) 接口派生类就无法以任何方式更改它从其基类继承的接口映射。例如,在下面的声明中

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();           // invokes Control.Paint();
t.Paint();           // invokes TextBox.Paint();
ic.Paint();          // invokes Control.Paint();
it.Paint();          // invokes 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();           // invokes Control.Paint();
t.Paint();           // invokes TextBox.Paint();
ic.Paint();          // invokes Control.Paint();
it.Paint();          // invokes 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 的实现。

1.1.2 接口重新实现

一个类若继承了某个接口的实现则只要将该接口列入它的基类列表中就可以重新实现 (re-implement) 该接口。

接口的重新实现与接口的初始实现遵循完全相同的接口映射规则。因此,继承的接口映射不会对为重新实现该接口而建立的接口映射产生任何影响。例如,在下面的声明中

interface IControl
{
void Paint();
}

class Control: IControl
{
void IControl.Paint() {...}
}

class MyControl: Control, IControl
{
public void Paint() {}
}

Control IControl.Paint 映射到 Control.IControl.Paint 并不影响 MyControl 中的重新实现该重新实现将 IControl.Paint 映射到 MyControl.Paint

继承的公共成员声明和继承的显式接口成员声明可以参与重新实现接口的接口映射过程。例如

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() {}
}

在此Derived IMethods 的实现将接口方法映射到 Derived.FBase.IMethods.GDerived.IMethods.H Base.I

当类实现接口时它还隐式实现该接口的所有基接口。与此类似,接口的重新实现也同时隐式地对该接口的所有基接口进行重新实现。例如

interface IBase
{
void F();
}

interface IDerived: IBase
{
void G();
}

class C: IDerived
{
void IBase.F() {...}

void IDerived.G() {...}
}

class D: C, IDerived
{
public void F() {...}

public void G() {...}
}

在此IDerived 的重新实现也重新实现 IBase并将 IBase.F 映射到 D.F

1.1.3 抽象类和接口

与非抽象类类似抽象类也必须为在该类的基类列表中列出的接口的所有成员提供它自己的实现。但是,允许抽象类将接口方法映射到抽象方法上。例如

interface IMethods
{
void F();
void G();
}

abstract class C: IMethods
{
public abstract void F();
public abstract void G();
}

这里IMethods 的实现将 F G 映射到抽象方法上这些抽象方法必须在从 C 派生的非抽象类中重写。

注意显式接口成员实现本身不能是抽象的但是当然允许显式接口成员实现调用抽象方法。例如

interface IMethods
{
void F();
void G();
}

abstract class C: IMethods
{
void IMethods.F() { FF(); }

void IMethods.G() { GG(); }

protected abstract void FF();

protected abstract void GG();
}

这里 C 派生的非抽象类被要求重写 FF GG从而提供 IMethods 的实际实现。

阅读(2281) | 评论(0)


版权声明:编程爱好者网站为此博客服务提供商,如本文牵涉到版权问题,编程爱好者网站不承担相关责任,如有版权问题请直接与本文作者联系解决。谢谢!

评论

暂无评论
您需要登录后才能评论,请 登录 或者 注册