不可变类和子类

2023-11-22

我正在尝试了解可变/不可变类,我遇到了这个帖子

提供的部分答案是:

如果你想强制不变性,你就不能有子类。看 例如 java.lang.String,由于这个原因它是最终类: 防止人们对 String 进行子类化以使其可变。

好吧我明白了but,你会如何处理这个问题。假设您的任务是创建 3 个 Employee 类:Accountant、ITDepartment 和 QualityAssurance。现在,您可以创建一个名为 Employee 的抽象类,它具有可供所有人共享的通用方法(员工 ID、姓名、工资等),但是,您的类不再是不可变的。

使用Java,那么你会如何解决这个问题呢?您会创建这 3 个类,将它们设为最终类,并且不实现抽象方法吗? (所以,没有任何子类化)或者您会使用接口,并仅提供 getter 吗?


如果你想强制不变性,你就不能有子类。

这几乎是正确的,但并不完全正确。重申一下:

如果要强制不变性,则必须确保所有子类都是不可变的。

允许子类化的问题在于,通常任何可以编写类的人都可以对任何公共非最终类进行子类化。

但所有子类都必须调用其超类的构造函数之一。包私有构造函数只能由同一包中的子类调用。

If you 密封包装为了控制包中包含哪些类,您可以限制子类化。首先定义一个你想要子类化的类:

public abstract class ImmutableBaseClass {
  ImmutableBaseClass(...) {
    ...
  }
}

由于所有子类都必须有权访问超级构造函数,因此您可以确保您定义的包中的所有子类都遵循不可变的规则。

public final class ImmutableConcreteClass extends ImmutableBaseClass {
  public ImmutableConcreteClass(...) {
    super(...);
  }
}

要将其应用到您的示例中,

public abstract class Employee {
  private final Id id;
  private final Name name;

  // Package private constructor in sub-classable class.
  Employee(Id id, Name name, ...) {
    // Defensively copy as necessary.
  }
}

public final class Accountant extends Employee {
  // Public constructos allowed in final sub-classes.
  public Accountant(Id id, Name name, ...) {
    super(id, name, ...);  // Call to super works from same package.
  }
}

public final class ITWorker extends Employee {
  // Ditto.
  public ITWorker(Id id, Name name, ...) {
    super(id, name, ...);
  }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

不可变类和子类 的相关文章

  • Java - 因内存不足错误而关闭

    关于如何最好地处理这个问题 我听到了非常矛盾的事情 并且陷入了以下困境 OOME 会导致一个线程崩溃 但不会导致整个应用程序崩溃 我需要关闭整个应用程序 但不能 因为线程没有剩余内存 我一直认为最佳实践是让它们离开 这样 JVM 就会死掉
  • 如何使用Spring WebClient进行同步调用?

    Spring Framework in 休息模板 https docs spring io spring framework docs current javadoc api org springframework web client R
  • “java.io.IOException:连接超时”和“SocketTimeoutException:读取超时”之间有什么区别

    如果我设置一个套接字 SoTimeout 并从中读取 当读取时间超过超时限制时 我会收到 SocketTimeoutException 读取超时 这是我的例子中的堆栈 java net SocketTimeoutException Read
  • Oracle Java 教程 - 回答问题时可能出现错误

    我是 Java 新手 正在阅读 Oracle 教程 每个部分之后都有问题和答案 我不明白一个答案中的一句话 见下面的粗体线 来源是https docs oracle com javase tutorial java javaOO QandE
  • 如何在 Openfire 中使用 smack

    你好 我计划开发一个可以连接到 gtalk facebook 等的聊天客户端 我决定将 smack API 与 openfire 一起使用 但我需要很少的指导来了解如何将它与 openfire 服务器一起使用 openfire 是否提供了基
  • (Java) App Engine 中的静态文件无法访问

    The 示例文档 http code google com appengine docs java gettingstarted staticfiles html表示您只需将文件放在 war 或子目录 中 并且应该可以从主机访问它们 只要它
  • 文本在指定长度后分割,但不要使用 grails 打断单词

    我有一个长字符串 需要将其解析为长度不超过 50 个字符的字符串数组 对我来说 棘手的部分是确保正则表达式找到 50 个字符之前的最后一个空格 以便在字符串之间进行彻底的分隔 因为我不希望单词被切断 public List
  • 埃拉托色尼筛法 - 实现返回一些非质数值?

    我用 Java 实现了埃拉托斯特尼筛法 通过伪代码 public static void sieveofEratosthenes int n boolean numArray numArray new boolean n for int i
  • 从休眠乐观锁定异常中恢复

    我有一个这样的方法 Transactional propagation Propagation REQUIRES NEW public void doSomeWork Entity entity dao loadEntity do some
  • Java、Spring:使用 Mockito 测试 DAO 的 DataAccessException

    我正在尝试增加测试覆盖率 所以我想知道 您将如何测试 DAO 中抛出的 DataAccessExceptions 例如在一个简单的 findAll 方法中 该方法仅返回数据源中的所有数据 就我而言 我使用 Spring JdbcTempla
  • 我们如何测试包私有类?

    我正在看书Effective Java in Item 13 Minimize the accessibility of classes and members 它提到 为了方便测试 您可能想让类 接口或成员更易于访问 这在某种程度上是好的
  • 如何通过 Android 按钮单击运行单独的应用程序

    我尝试在 Android 应用程序中添加两个按钮 以从单独的两个应用程序订单系统和库存系统中选择一个应用程序 如图所示 我已将这两个应用程序实现为两个单独的 Android 项目 当我尝试运行此应用程序时 它会出现直到正确选择窗口 但是当按
  • 在 Clojure 中解压缩 zlib 流

    我有一个二进制文件 其内容由zlib compress在Python上 有没有一种简单的方法可以在Clojure中打开和解压缩它 import zlib import json with open data json zlib wb as
  • JAVA中遍历JSON数据

    我是 JSON 新手 我使用 HTTPUrlConnections 并在 JAVA 程序中获得一些响应 响应数据将类似于 data id 1 userId 1 name ABC modified 2014 12 04 created 201
  • 避免 Java 中的重复导入:继承导入?

    有没有办法 继承 导入 Example 常见枚举 public enum Constant ONE TWO THREE 使用此枚举的基类 public class Base protected void register Constant
  • Lombok @Builder 不创建不可变对象?

    在很多网站上 我看到 lombok Builder 可以用来创建不可变的对象 https www baeldung com lombok builder singular https www baeldung com lombok buil
  • 如何从 Ant 启动聚合 jetty-server JAR?

    背景 免责声明 I have veryJava 经验很少 我们之前在 Ant 构建期间使用了 Jetty 6 的包装版本来处理按需静态内容 JS CSS 图像 HTML 因此我们可以使用 PhantomJS 针对 HTTP 托管环境运行单元
  • 源值 1.5 的错误已过时,将在未来版本中删除

    我使用 scala maven plugin 来编译包含 scala 和 java 代码的项目 我已经将源和目标设置为1 7 但不知道为什么maven仍然使用1 5 这是我在 pom xml 中的插件
  • 使用 Java https 上传到 Imgur v3 错误

    我目前正在尝试使用他们当前的 API v3 上传到 imgur 但是我不断收到错误 错误 javax net ssl SSLException 证书中的主机名不匹配 api imgur com imgur com OR imgur com
  • 将对象从手机共享到 Android Wear

    我创建了一个应用程序 在此应用程序中 您拥有包含 2 个字符串 姓名和年龄 和一个位图 头像 的对象 所有内容都保存到 sqlite 数据库中 现在我希望可以在我的智能手表上访问这些对象 所以我想实现的是你可以去启动 启动应用程序并向左和向

随机推荐

  • “删除不必要的使用”在 Visual Studio 2015 中不起作用

    我有几个项目的解决方案 Remove unnecessary usings正在参与除一个项目之外的所有项目 为什么Remove unnecessary usings命令not在一些项目中工作 Edit 正如你所看到的Before图像没有Re
  • CompletableFuture 链结果

    我试图将方法的调用 结果链接到下一个调用 我收到编译时错误 methodE 因为如果无法从上一次调用中获取 objB 的引用 如何将上一个调用的结果传递到下一个链 我完全误解了这个过程吗 Object objC CompletableFut
  • 抽象类与所有方法抽象和接口之间的区别?

    我有一次面试 面试官首先问我具有所有抽象方法的抽象类和接口之间有什么区别 我回答说 如果以后需要继承一些东西 如果你已经扩展了一个类 你就无法继承 然后 他说这是一种情况 永远不需要延长任何其他课程 你必须执行合同 在这种情况下 抽象类和接
  • 为什么欧洲/柏林时区的偏移量为 0:53?

    示例代码 from datetime import datetime timezone import pytz tzstring Europe Berlin t1 datetime 2016 6 16 2 0 tzinfo pytz tim
  • 找到最接近某个值的公约数的有效算法?

    我有两个号码 x1 and x2 对于一个号码y 我想计算的公约数x1 and x2尽可能接近y 有一个有效的算法吗 我相信是时候重新表述我的问题并且更加清楚了 这与整数无关 所以 假设我们有两个数字x1 and x2 比如说 用户输入一个
  • React 访问 axios 拦截器中的 redux 存储

    I want to access redux store in axios s interceptor which configures jwt token so I import the store into the API js fil
  • Toolkit.getDefaultToolkit().createImage() 与 ImageIO.read()

    我正在使用 Swing 创建一个 UI 我想在JLabel 我使用的代码如下 JLabel label new JLabel new ImageIcon ImageIO read new File img jpg 如果我使用的话效果很好pn
  • 对矩阵的每个元素使用 max

    gt x lt array 10 10 dim c 4 5 gt x 1 2 3 4 5 1 10 6 2 2 6 2 9 5 1 3 7 3 8 4 0 4 8 4 7 3 1 5 9 如何将 max x 0 应用于每个元素 以便得到这个
  • JavaFX TreeView 的多种对象类型? (和更多)

    我目前有以下对象数据结构 Item 字符串名称 信息的数组列表 特点 字符串名称 收集Item Account 字符串名称 收集特点 最多 8 个 我想制作一个如下所示的 TreeView Root invisible Jake Accou
  • 在 Linux 上使用 Mono 运行 SignalR .Net 客户端 - 可能吗?

    有谁有运行经验SignalR net 客户端在单声道上 我正在考虑将其用于需要运行跨平台的进程 需要连接到互联网托管的 SignalR Hub 我创建了一个在 mono 框架下使用 signalr 客户端工作的示例项目 https gith
  • PHP访问控制系统

    我是使用 PHP 和 MySQL 创建 Web 应用程序的团队的一员 该应用程序将有多个具有不同角色的用户 该应用程序还将以地理分布的方式使用 因此 我们需要创建一个在以下两个级别运行的访问控制系统 控制特定 php 页面的用户权限 即根据
  • 三次贝塞尔曲线上的最近点?

    如何沿着三次贝塞尔曲线找到最接近平面上任意点 P 的点 B t 我编写了一些快速而简单的代码来估计任意阶贝塞尔曲线的这一点 注意 这是伪暴力 而不是封闭式解决方案 Demo http phrogz net svg closest point
  • 使用 EclipseLink MOXy (JAXB) 将子类编组为 JSON 时是否可以隐藏“@type”条目?

    我即将开发一个基于 JAX RS 的 RESTful Web 服务 并使用 MOXy JAXB 来自动生成 Web 服务的 JSON 响应 一切都很酷 但由于 Web 服务将是基于 JavaScript 的 Web 应用程序的后端 因此可以
  • 具有提升权限的 CreateProcessAsUser

    我的服务在本地系统权限下运行 需要在用户会话中启动具有管理员权限的应用程序 我得到的是 WTSGetActiveConsoleSessionID WTSQueryUserToken用于会话 ID CreateProcessAsUser 问题
  • 让 Discord Bot 在 repl.it 上保持在线

    我该如何使用repl it对于我的 Python Discord Bot 并保持其 24 7 运行 我以前用过keep alive但由于某种原因它停止工作 有没有人有什么建议 我不断在控制台中收到此错误 172 18 0 1 2019 年
  • Python 的 site-packages 目录是什么?

    目录site packages在各种Python相关文章中都提到过 它是什么 我该如何使用它 site packages is the 目标目录手动构建的 Python 包 当您从源代码构建并安装 Python 包时 使用迪斯图尔斯 可能通
  • 如何从 Visual Code 中的快速打开菜单打开多个文件?

    我想知道是否可以从 Visual Code 中的快速打开菜单中打开多个文件 使用cmd p默认快捷方式 如果能够选择结果中的前 N 个文件并立即打开它们 将会很有帮助 例如 我可以输入 test device js 并且可以打开前 3 个文
  • Prolog 中的幂函数

    我的电源功能出了什么问题 pow 0 1 pow X Y Z pow X Y 1 X Z pow 2 3 Z ERROR Out of global stack 你的 Y 不会递减 你不能使用像函数这样的谓词 您还必须将 Z 与乘法结果统一
  • 如何在Django的同一页面上插入2个不同的表单

    我必须在同一页面中插入两个表单 1 登记表 2 登录表格 所以如果我在views py中使用它 if request method POST form registrationForm request POST if form is val
  • 不可变类和子类

    我正在尝试了解可变 不可变类 我遇到了这个帖子 提供的部分答案是 如果你想强制不变性 你就不能有子类 看 例如 java lang String 由于这个原因它是最终类 防止人们对 String 进行子类化以使其可变 好吧我明白了but 你