【发布时间】:2019-10-15 18:55:57
【问题描述】:
我正在设计一个类层次结构,我在标题中遇到了这个问题,这里是它的一个较小的抽象:
public abstract class A {
private C c;
public A(C c) {
this.c = c;
}
// ...
}
public class B extends A {
private int a;
private int b;
// ...
public B(int a, int b, ... /* and more but no object of C */) {
super(new C(this)); // <-- this is the point, got error:
// can't access `this` .
this.a = a;
this.b = b;
// ...
}
}
public class C {
private A a;
public C(A a) {
this.a = a;
}
}
简而言之:A 需要保持对C 的引用,反之亦然,但是两者都应该在它们的构造函数中完成,并且在两者都构造完成之后,字段A a 和C c 不应该是改变了,所以我让他们private。那么在这种情况下,最佳做法是什么?
下面其实不是一个很好的例子,但重点是我有一种情况需要做上面尝试做的事情。
(更多上下文:现在假设我将class A 的private C c; 更改为
private List<C> someCs;
即:A 是C 的容器,因此在某些情况下需要对这些C 进行排序。对于每个C 的某些客户端,客户端需要知道它的父级是什么,即它属于哪个A。在这种情况下,我需要两个方向的参考。)
【问题讨论】:
-
我认为您需要重新考虑您的设计决策,您确定只有一个方向的耦合还不够吗?或者至少只需要在构造函数中设置一个?另外,对于无法更改的实例变量,最好使用
final。 -
@JoakimDanielson:让我提供更多背景信息。已更新。
-
类之间存在固有的循环依赖关系。因此,它不再是等级制度。我们应该先看看如何删除它。
-
@AnindyaDutta:所以这通常是一种难闻的代码?
-
鉴于更新我认为不需要在任一类的构造函数中设置它,您在构造函数中的 A 中创建列表但您真的没有列表的内容吗?当 C 对象添加到列表中时,C 更可能需要从 C 内部调用的方法
setParent(以this作为参数)。想一想,既然列表是 A 中的实例变量,为什么 A 的实例会保存 C 的任何其他实例而不是它的父级实例?
标签: java