您的位置:首页 > 产品设计 > UI/UE

Effective C# Item 20: Distinguish Between Implementing Interfaces and Overriding Virtual Functions

2006-11-13 08:52 701 查看
Effective C# Item 20: Distinguish Between Implementing Interfaces and Overriding Virtual Functions

乍看之下,实现接口和重写虚方法是相似的,它们都为一个声明好的成员提供了定义。这种看法是错误的。实现接口和重写虚方法是有很大区别的。在默认情况下,在接口中声明的成员不是虚拟的。派生类不能够重写基类中实现的接口。

有一种方法可以让派生类修改基类中接口的实现。要实现这一点,我们需要为派生类创建一个钩子(hook)。

下面我们举一个例子,一个简单的接口和一个类对接口的实现如下:

interface IMsg
public class MyClass : IMsg
public class MyDerivedClass : MyClass
MyDerivedClass d = new MyDerivedClass();
d.Message(); //结果为"MyDerivedClass"
IMsg m = d as IMsg;
m.Message(); //结果为"MyClass"

接口方法不是虚拟的,当我们实现接口时,就是为我们的类声明了一个有特殊含义的具体实现。

但是有时候我们希望创建接口,在基类中实现,并且在派生类中修改它们的行为。这是可以做到的。我们有两种选择,如果我们的基类是不可达的,那么我们可以在派生类中重新实现该接口:

public class MyDerivedClass : MyClass, IMsg
MyDerivedClass d = new MyDerivedClass();
d.Message(); //结果为"MyDerivedClass"
IMsg m = d as IMsg;
m.Message(); //结果为"MyDerivedClass"

我们依然需要使用new关键字来声明MyDerivedClass.Message()方法。但是这仍然存在问题。通过基类的引用我们仍然会得到基类中的实现版本。

解决这个问题的唯一方法是修改基类,将这个接口方法声明为虚拟的。

public class MyClass : IMsg
public abstract class MyClass : IMsg
{
public virtual void Message();
}
现在我们可以实现一个接口而不完全实现其中的方法。因为将方法声明为抽象的,我们必须在派生类中提供它的具体实现。IMsg是MyClass声明中的一部分,但是其中方法的具体定义却转移到派生类中实现。

实现接口比创建和重写虚方法有更多的选择。我们可以将实现声明为密封的,虚拟的,或者抽象的。我们可以根据具体情况来决定派生类是否可以修改基类中对接口的默认实现。

译自 Effective C#:50 Specific Ways to Improve Your C# Bill Wagner著

回到目录
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐