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著
回到目录
乍看之下,实现接口和重写虚方法是相似的,它们都为一个声明好的成员提供了定义。这种看法是错误的。实现接口和重写虚方法是有很大区别的。在默认情况下,在接口中声明的成员不是虚拟的。派生类不能够重写基类中实现的接口。
有一种方法可以让派生类修改基类中接口的实现。要实现这一点,我们需要为派生类创建一个钩子(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著
回到目录
相关文章推荐
- Effective C#之20:Distinguish Between Implementing Interfaces and Overriding Virtual Functions
- Effective C# Item 6: Distinguish Between Value Types and Reference Types
- Item 6:Distinguish between prefix and postfix forms of increment and decrement operators.(More Effective C++)
- Item 1:Distinguish between pointers and references.(More Effective C++)
- Item 9: Never call virtual functions during construction or destruction(Effective C++)
- Item 6: Distinguish Between Value Types and Reference Types
- More Effective C# Item 7. Do Not Create Generic Specialization on Base Classes or Interfaces
- Effective C# Item 9: Understand the Relationships Among ReferenceEquals(),static Equals(),instance Equals,and operator==
- Item 18: Distinguish Between Value Types and Reference Types(Effective C#)
- Effective C# Item19: Prefer Defining and Implementing Interfaces to Inheritance
- Item 34: Differentiate between inheritance of interface and inheritance of implementation(Effective C++)
- Effective C# Item 15: Utilize using and try/finally for Resource Cleanup
- 【转】Effective C# Item 15: Utilize using and try-finally
- Effective C++ Item 35 Consider alternatives to virtual functions
- Item 41: Understand implicit interfaces and compile-time polymorphism(Effective C++)
- Item 18: Make interfaces easy to use correctly and hard to use incorrectly(Effective C++)
- Effective C++ Item 18 Make interfaces easy to use correctly and hard to use incorrectly
- Effective C++ Item 34 Differentiate between inheritance of interface and inheritance of implementation
- Effective C# Item 26: Implement Ordering Relations with IComparable and IComparer
- Item 22: Prefer Defining and Implementing Interfaces to Inheritance(Effective C#)