使用组合和继承时避免 Java 中的菱形

Avoiding diamond shapes in Java when using composition and inheritance

我一直在构建一个有五个 class 的系统,另一个 class 包含初始化、显示和修改上述五个不同对象的主要方法 class是的。我了解如何使用继承来采用治疗师和患者 classes 中的字段(例如 name、address phonenumber 字段)parent-class,以及如何使用组合(至少在理论上)构建咨询对象和患者账单 class。

但是,我对如何在 Therapist class 中存储一个名为 therapist name 的字段并在我调用对象时显示它感到困惑病人。我已经包含了一个 class 图表,说明我认为它应该是什么样子,但显然这形成了一个菱形,这是 java 中的一个大禁忌。我的 class 图表中的内容是否有效?

任何人都可以举例说明我如何在治疗师 class 中存储 治疗师姓名 然后 移动 该数据当我创建它的对象时,member over to patient?

这是一张图表:

钻石问题对于 Java 并不存在,因为 Java 只支持签名的多重继承,而不支持实现(虽然我不确定它如何与 Java 8 个接口默认方法——我还没有完全弄乱它们)。 multi-inheritance-of-implementation语言中的菱形问题是指一个class通过两个不同的parentclass继承同一个grandparentclass的问题。例如,在 C++ 中,您将获得具有两个不同的 grandparent 实例的孙子(每个 parent class 实例),因此您可以通过转换 object 到 grandparent,取决于演员来自哪个 parent;或者你将有一个 grandparent 实例,由两个 parents 共享——他们可能会使用不同的语义更新 grandparent。

在这种情况下,如果要向 Patient 添加一个 therapistName 字段,只需添加一个名为 therapistName 的字段并通过构造函数参数或 setter。这里没有问题。

底线:菱形模式只是no-no实现的多重继承,Java不支持(同样,可能不包括接口默认方法)。由组合引起的菱形不是反模式,也不会给您带来痛苦,除了可能使初始化 and/or 处理逻辑更加繁琐。

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

检查下面的箭头。

而且你写错了,患者和治疗师之间的关系是聚合关系。一个组合关系,你可以把它看成"part of"。我在这里也写了一个关于它的简单线程,阅读: