在我工作的一个大型项目中,我正在考虑建议其他程序员,如果他们没有考虑应如何继承其类,则应始终密封其类。通常,经验不足的程序员永远不会考虑这一点。
我觉得奇怪的是,在Java和C#中,默认情况下类是非密封的/非最终的。我认为将类密封起来可以大大提高代码的可读性。
注意,这是内部代码,如果极少数情况需要我们继承,我们可以随时更改。
你有什么经验?我对此想法有些抵触。那些懒得打扰他们的人sealed吗?
sealed
好的,因为很多其他人都在考虑…
是的,我认为建议默认情况下密封类是完全合理的。
设计继承,或禁止继承。
设计继承是 很难 ,而且可以让你实现 更少的 灵活,特别是如果你有虚拟方法,其中一个调用其他。也许它们是超载,也许不是。 必须记录 一个调用另一个方法的事实,否则您将无法安全地覆盖这两种方法-您不知道何时调用该方法,或者您是否可以安全地调用另一种方法而不会冒堆栈溢出的危险。
现在,如果您以后想要更改哪个方法在更高版本中调用哪个方法,则不能-可能会破坏子类。所以在“灵活性”的名字,你实际上已经取得了实现 少 灵活,而不得不更加紧密地记录您的实现细节。对我来说,这听起来不是一个好主意。
接下来是不变性-我喜欢不变类型。我发现它们比可变类型更容易推理。这是Joda Time API比在Java中使用Date和更好的原因之一Calendar。但是,从来没有人 知道 未密封的类是不可变的。如果我接受type的参数Foo,则可以依赖于中 声明 的属性 Foo 不能随时间更改,但是我不能依靠对象本身不被修改- 子类中可能存在可变的属性。如果该属性也被某些虚拟方法的覆盖所使用,那么Heaven可以帮助我。告别不变性的许多好处。(具有讽刺意味的是,Joda Time具有非常大的继承层次结构-经常说“子类应该是不可变的。庞大的继承层次结构Chronology使得在移植到C#时很难理解。)
Date
Calendar
Foo
Chronology
最后,还有过度使用继承的方面。就个人而言,在可行的情况下,我更倾向于组合而不是继承。我喜欢接口的多态性, 有时会 使用实现的继承- 但根据我的经验,这很少适合。使类密封,可以避免不 恰当地 从组合更适合的地方派生它们。
编辑:我还想向读者介绍2004年Eric Lippert的博客文章,其中介绍了为什么密封这么多框架类。我希望在很多地方.NET提供一个我们可以使用的 接口 以实现可测试性,但这是一个稍微不同的要求…