为了账号安全,请及时绑定邮箱和手机立即绑定

我们可以在不使用 final 关键字的情况下避免继承吗?

我们可以在不使用 final 关键字的情况下避免继承吗?

隔江千里 2021-09-12 20:07:36
我只是想知道我可以有 2 个类 A 和 B。我不想让 B 类扩展 A 类。我应该在 A 类中应用什么技术,以便 B 类不能继承 A 类。不想使A类最终。任何其他解决方案而不是使 A 类成为最终解决方案?
查看完整描述

3 回答

?
函数式编程

TA贡献1807条经验 获得超9个赞

事实上,我尝试遵循的实践,以及 Josh Bloch 在他的 Effective Java 书中推荐的实践,正是你被告知的规则的逆向规则:除非你考虑过继承,否则将你的类设计为被继承,并记录了您的类必须如何继承,您应该始终禁用继承。

我建议您阅读 Effective Java 的这一章(您不会后悔购买它),并将其展示给告诉您此规则的人。

禁止继承的最明显原因是不可变性。不可变对象易于使用(只有一种状态),可以缓存,在许多对象之间共享,并且本质上是线程安全的。如果该类是可继承的,则任何人都可以扩展该类并通过添加可变属性使其可变。


查看完整回答
反对 回复 2021-09-12
?
RISEBY

TA贡献1856条经验 获得超5个赞

这在“好的方式”中是不可能的。Java 语言允许您final在类定义中使用关键字,或者不使用关键字。


正如其他人指出的那样:您可以将所有构造函数设为私有,然后子类化变得几乎不可能,因为子类构造函数没有可调用的超类构造函数。


如果您需要实例化 A,您仍然可以使用工厂方法,例如:


public class A {

  private A() { ... }

  private A(String foo) { ... }


  public static A newInstance(String foo) { return new A(foo); }

例如。


但请记住:代码是为您的人类读者编写的。如果您的目的是开设最后一堂课,那么正确的答案是使用该关键字final。


另外:使您的类成为 final 允许 JIT 做更多的事情,因为它在任何时候都不必担心多态性(因此它可以直接内联方法代码,无需任何额外检查)。所以使用final可以稍微提高性能。另一方面,它限制了您对事物进行单元测试的能力(例如:标准 Mockito 不能模拟最终类)。


查看完整回答
反对 回复 2021-09-12
?
慕容708150

TA贡献1831条经验 获得超4个赞

您可以将 A 类的构造函数标记为私有。:)

PS:如果您还想避免反射攻击,则从构造函数中抛出一些错误并将其标记为私有。


查看完整回答
反对 回复 2021-09-12
  • 3 回答
  • 0 关注
  • 173 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信