《Effective C#》某些地方实在是对不起Effective这个词(II)
这次我们来关注条款20:Distinguish Between Implementing Interfaces and Overriding Virtual Functions。
条款20的解释中,作者的目标是实现一个接口,并在派生类中改变它的实现,即:
不好。
先说new掉基类public方法有什么弊端。一般情况下,接口定义了行为,抽象类的公共方法定义了这些行为的规范。比方说完成一个功能A,中间有若干步骤(k1,k2,k3...),完成整个功能,必须按照k1,k2,k3的顺序执行。所谓的“OOD”则一般把k1,k2,k3定义成protected virtual,允许派生类override。现在,如果派生类new掉了A会有什么后果呢?能保证这些中间步骤的顺序执行?
OK,现在各位发现基类中public virtual方法也有同样的问题。所以,书中建议的方法都不好。
那么怎么做才happy一些呢?
基类使用public方法实现接口,并提供一个protected virtual的internal方法完成真正的操作,派生类只override这些方法。
最后做个总结:
1、派生类尽可能不new掉基类的public方法。如果出现这样的需求,那一定是基类的设计有问题。
2、基类所有的virtual和abstract方法应该只是protected。
3、(加上上篇提到的结论)尽可能使用抽象类,而不是直接实现接口。(这个可以仔细看看msdn,仔细看看.net framework的实现,微软就是建议这么做)
4、(补上篇结论中提到的一点)方法参数,泛型中的T都应该限制最小化。
条款20的解释中,作者的目标是实现一个接口,并在派生类中改变它的实现,即:
interface IMsg
{
void Message();
}
// public class MyBaseClass : IMsg
//
// public class MyDerivedClass : MyBaseClass
//
MyBaseClass b = new MyBaseClass();
b.Message()
MyDerivedClass d = new MyDerivedClass();
d.Message()
//output:
//MyBaseClass
//MyDerivedClass
作者提到,要实现它,有两种选择,一是在派生类中使用new关键字重新实现接口;二是在基类中public virtual void Message(),并在派生类中override。并且建议override。但是这样做很好吗?{
void Message();
}
// public class MyBaseClass : IMsg
//
// public class MyDerivedClass : MyBaseClass
//
MyBaseClass b = new MyBaseClass();
b.Message()
MyDerivedClass d = new MyDerivedClass();
d.Message()
//output:
//MyBaseClass
//MyDerivedClass
不好。
先说new掉基类public方法有什么弊端。一般情况下,接口定义了行为,抽象类的公共方法定义了这些行为的规范。比方说完成一个功能A,中间有若干步骤(k1,k2,k3...),完成整个功能,必须按照k1,k2,k3的顺序执行。所谓的“OOD”则一般把k1,k2,k3定义成protected virtual,允许派生类override。现在,如果派生类new掉了A会有什么后果呢?能保证这些中间步骤的顺序执行?
OK,现在各位发现基类中public virtual方法也有同样的问题。所以,书中建议的方法都不好。
那么怎么做才happy一些呢?
基类使用public方法实现接口,并提供一个protected virtual的internal方法完成真正的操作,派生类只override这些方法。
最后做个总结:
1、派生类尽可能不new掉基类的public方法。如果出现这样的需求,那一定是基类的设计有问题。
2、基类所有的virtual和abstract方法应该只是protected。
3、(加上上篇提到的结论)尽可能使用抽象类,而不是直接实现接口。(这个可以仔细看看msdn,仔细看看.net framework的实现,微软就是建议这么做)
4、(补上篇结论中提到的一点)方法参数,泛型中的T都应该限制最小化。
posted on 2007-07-19 14:59 Nineteen@newsmth 阅读(2586) 评论(31) 编辑 收藏 举报