在我工作的一个大项目中,我正在考虑推荐其他程序员,如果他们没有考虑如何对他们的类进行子类化,就应该始终密封他们的类.通常情况下,经验不足的程序员从不考虑这一点.
我觉得奇怪的是,在Java和C#中,默认情况下类是非密封/非最终的.我认为密封类可以极大地提高代码的可读性.
请注意,这是我们可以随时更改的内部代码,如果出现罕见的情况,我们需要子类化.
你的经历是什么?我对这个 idea 遇到了不少阻力.人们是不是懒得打sealed
?
在我工作的一个大项目中,我正在考虑推荐其他程序员,如果他们没有考虑如何对他们的类进行子类化,就应该始终密封他们的类.通常情况下,经验不足的程序员从不考虑这一点.
我觉得奇怪的是,在Java和C#中,默认情况下类是非密封/非最终的.我认为密封类可以极大地提高代码的可读性.
请注意,这是我们可以随时更改的内部代码,如果出现罕见的情况,我们需要子类化.
你的经历是什么?我对这个 idea 遇到了不少阻力.人们是不是懒得打sealed
?
好的,就像其他很多人都参与进来的那样……
是的,我认为建议默认密封类是完全合理的.
This goes along with the recommendation from Josh Bloch in his excellent book Effective Java, 2nd edition:
设计继承,或禁止继承.
继承设计为hard,可以使您的实现less灵活,特别是如果您有虚方法,其中一个方法调用另一个方法.可能是超载,也可能不是.一个调用另一个must be documented的事实是,否则您不能安全地覆盖这两个方法中的任何一个-您不知道它何时被调用,也不知道调用另一个方法是否安全而不会有堆栈溢出的风险.
现在,如果您以后想更改哪个方法在以后的版本中调用哪个方法,您不能更改,您可能会 destruct 子类.因此,以"灵活性"的名义,您实际上已经使实现less灵活,并且必须更详细地记录您的实现细节.对我来说,这听起来不是个好主意.
接下来是不变性——我喜欢不变性类型.我发现它们比可变类型更容易推理.这就是为什么Joda Time API比在Java中使用Date
和Calendar
更好的原因之一.但一个未密封的类永远不可能是不变的.如果我接受Foo
类型的参数,我可能可以依赖于属性declared in 103不随时间改变,但我不能依赖对象本身不被修改——子类中可能有一个可变属性.如果该属性也被某个虚拟方法的重写所使用,请god 保佑我.挥手告别不变性的许多好处.(具有讽刺意味的是,Joda Time有非常大的继承层次 struct ——通常会说"子类应该是不可变的.Chronology
的大继承层次 struct 使移植到C#时很难理解.)
最后,还有过度使用继承的问题.就我个人而言,在可行的情况下,我更喜欢构图而不是继承.我喜欢接口的多态性,我使用实现的继承——但这在我的经验中很少是很合适的.将类密封起来可以避免它们从更适合组合的地方派生出来.
编辑:关于为什么这么多框架类是密封的,我还想告诉读者Eric Lippert's blog post from 2004.有很多地方我希望.NET提供一个interface,我们可以用它来实现可测试性,但这是一个稍微不同的要求……