我目前正在阅读Joshua Bloch的Effective Java,第17项是'继承的设计和文档,否则禁止它'。作者建议默认禁止继承。
默认情况下声明类final是否安全,如果需要扩展类,则在以后的版本中删除final关键字?它是否会破坏与以前版本编译的代码的向后兼容性?
如果是这样的话,看起来更安全的做法是让所有课程都成为最终版本,并且如果有良好的支持需求,则只在将来的版本中将其删除。
答案 0 :(得分:10)
它既不破坏二进制也不破坏源兼容性。这就是让课程最终成为一个好主意的原因之一;改变你的想法总是可以的。
The Java Language Specification, §13.4.2 ,有关于二进制兼容性的以下内容:
将声明为
final
的类更改为不再声明final
不会破坏与预先存在的二进制文件的兼容性。
我想你仍然可以构成一个可以打破程序的解释性例子;比如字节码 - 生成一个继承自所谓的final
类的类,然后加载生成的类并依赖于获取VerifyError
。
答案 1 :(得分:2)
我对此的看法:
删除类上的final
不会立即导致问题。但请考虑一下:
有一个名为AdamsFactory的最终课程,您将其更改为非最终成绩。两个月后,一位名叫迪尔伯特的新程序员加入了你的团队 他将你曾经的最终类子类化为ScottFactory,但打破了Liskov的Substitutability Principle。
然后他让你的ComicStripPrinter类使用ScottFactory而不是AdamsFactory。有些东西必然会破裂。
这让我们回到约书亚·布洛克所说的话:
如果您打算继承:请仔细设计并记录下来。如果你不打算继承,那就防止继承。
我希望我说的不是一个很大的负担。
编辑:
转到preface of Java Langauge Specification,搜索Joshua Bloch:)
答案 2 :(得分:2)
如果您正在设计类似Java Standard API的东西,数百万程序员将使用多年,是的,请像Joshua Bloch一样思考。前进演变至关重要。
99%的Java程序都没有。它们是为内部开发而开发的,API变化的影响很小,通常所有源代码都可用于重构。简单性是此类计划的关键。如果你有复杂和花哨的设计,或者你把所有时间都花在考虑最终与否,那么你就是在浪费时间。
我责备约书亚没有为他的建议设置适当的免责声明。