Effective C# 原则20:明辨接口实现和虚函数重载的区别
2009-02-19 08:16:36 来源:WEB开发网MyDerivedClass d = new MyDerivedClass( );
d.Message( ); // prints "MyDerivedClass".
IMsg m = d as IMsg;
m.Message( ); // prints "MyClass"
接口方法不是虚的,当你实现一个接口时,你就要在详细的相关类型中申明具体的实现内容。
但你可能想要创建接口,在基类中实现这些接口而且在派生类中修改它们的行为。这是可以办法到的。你有两个选择,如果不访问基类,你可以在派生类中重新实现这个接口:
public class MyDerivedClass : MyClass, IMsg
{
public new void Message()
{
Console.WriteLine( "MyDerivedClass" );
}
}
添加的IMsg让你的派生类的行为发生了改变,以至IMsg.Message现在是在派生类上使用的:
MyDerivedClass d = new MyDerivedClass( );
d.Message( ); // prints "MyDerivedClass".
IMsg m = d as IMsg;
m.Message( ); // prints "MyDerivedClass"
派生类上还是须要在MyDerivedClass.Message()方法上添加关键字new,这还是有一点隐患(参见原则29)。基类还是可以通过接口引用来访问:
MyDerivedClass d = new MyDerivedClass( );
d.Message( ); // prints "MyDerivedClass".
IMsg m = d as IMsg;
m.Message( ); // prints "MyDerivedClass"
MyClass b = d;
b.Message( ); // prints "MyClass"
唯一可以修正这个问题的方法是修改基类,把接口的申明修改为虚函数:
public class MyClass : IMsg
{
public virtual void Message()
{
Console.WriteLine( "MyClass" );
}
}
public class MyDerivedClass : MyClass
{
public override void Message()
{
Console.WriteLine( "MyDerivedClass" );
}
}
MyDerivedClass以及其它所有从MyClass派生的类可以申明它们自己的Message()方法。这个重载的版本每次都会调用:通过MyDerivedClass的引用,通过IMsg接口的引用,或者直接通过MyClass的引用。
如果你不喜欢混杂的虚函数概念,那就对MyClass的定义做一个小的修改:
public abstract class MyClass, IMsg
{
public abstract void Message();
}
是的,你可以用一个抽象方法来实现一个接口。通过申明一个接口内的抽象的方法,你可以让你的所有派生都必须实现这个接口。现在,IMsg接口成为了MyClass的一个组成部份,你的每一个派生类都必须实现它。
隐式接口实现,可以让你在一个类上隐藏公共的接口成员方法,而且也实现了这个接口。它在实现接口和虚函数重载上绕了几个圈。当有多个合适的函数版本时,你可以利用隐式接口的实现来限制用户的编码。在原则26讲到的IComparable习惯会详细的讨论这一点。
实现接口让我们有更多的选择,用于创建和重载虚函数。你可以创建隐秘的实现,虚的实现,或者抽象关联到派生类。你可以精确的决定,你的派生类如何以及何时,修改接口的默认实现。接口方法不是虚方法,而是一个独立的约定!
- ››Effective C# 原则40:根据需求选择集合
- ››Effective C# 原则41:选择DataSet而不是自定义的...
- ››Effective C# 原则42:使用特性进行简单的反射
- ››Effective C# 原则43:请勿滥用反射
- ››Effective C# 原则44:创建应用程序特定的异常类
- ››Effective C# 第6章:杂项
- ››Effective C# 原则45:选择强异常来保护程序
- ››Effective C# 原则47:选择安全的代码
- ››Effective C# 原则48:了解更多的工具和资源
- ››Effective C# 原则49:为C#2.0做好准备
- ››Effective C# 原则50:了解ECMA标准
- ››Effective C# 原则系列文章目录
赞助商链接