【问题标题】:Avoiding diamond shapes in Java when using composition and inheritance使用组合和继承时避免在 Java 中使用菱形
【发布时间】:2015-07-25 10:20:29
【问题描述】:

我一直在构建一个具有五个类的系统,另一个类包含用于初始化、显示和修改来自上述五个类的各种不同对象的主要方法。我了解如何使用继承从人(例如姓名,地址电话号码字段)父类中采用治疗师和患者类中的字段,以及如何使用组合(至少在理论上)从患者类构建咨询和账单对象。

但是,我对如何在 Therapist 类中存储一个名为 治疗师姓名 的字段并在调用患者对象时显示该字段感到困惑。我已经包含了一个关于我认为它应该是什么样子的类图,但显然这形成了一个菱形,这在 java 中是一个很大的禁忌。像我的类图中的东西这样的东西还能用吗?

谁能举例说明我如何将治疗师姓名存储在 Therapist 类中,然后在我创建对象时将该数据成员移动给患者? p>

这是一个图表:

【问题讨论】:

  • 谁告诉你这种安排是“不不不”?
  • 那是……实际上不是钻石。如果您想同时创建 Patient 和 Therapist 的子类,则可以使用钻石。你很好。
  • 您是否考虑过一个患者可能会使用多个治疗师?
  • @Bohemian 这听起来像是一个任务,如果只指定 1,我不会把事情复杂化到 N。
  • @Bohemian - 在阅读问题之前,我阅读了您的评论。我虽然你在对多重继承的疯狂发表讽刺评论:)

标签: java inheritance interface composition


【解决方案1】:

对于 Java 来说,钻石问题实际上并不存在,因为 Java 只支持签名的多重继承,而不是实现的多重继承(尽管我不确定它如何与 Java 8 接口默认方法一起工作——我没有搞砸他们那彻底呢)。多继承实现语言中的菱形问题是指一个类通过两个不同的父类继承同一个祖父类的问题。例如,在 C++ 中,您要么让孙子具有两个不同的祖父实例(每个父类一个),因此您可以通过将对象强制转换为祖父得到两种不同的结果,具体取决于强制转换来自哪个父级;或者您将拥有一个由父母双方共享的祖父母实例——他们可能会使用不同的语义更新祖父母。

在这种情况下,如果您想将therapistName 字段添加到Patient,只需添加一个名为therapistName 的字段并通过构造函数参数或setter 对其进行初始化。这里没有问题。

底线:菱形模式只是禁止实现的多重继承,Java 不支持(同样,可能不包括接口默认方法)。由组合导致的菱形不是反模式,也不会给您带来痛苦,除了可能会使初始化和/或处理逻辑更加麻烦。

【讨论】:

  • 感谢您的广泛回答!这真的为我解决了我的问题,并让我有信心在实践中尝试它。话虽如此,我不太清楚我从哪里得到的想法,即由成分引起的钻石会导致错误 - 这可能是我自己误解的结果。
【解决方案2】:

正如已经提到的关于你担心的钻石,我想在你的图表上做一些标记。

检查下面的箭头。

关于你写错的构图,病人和治疗师之间的关系是一种聚合关系。一种组合关系,您可以将其更多地视为“一部分”。我在这里也写了一个简单的帖子,阅读:Is this an aggregation?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-18
    • 1970-01-01
    • 2012-10-16
    • 1970-01-01
    • 2016-10-02
    • 1970-01-01
    相关资源
    最近更新 更多