说我有班级签名
Class1(Class2 c);
Class2(Class1 c);
如何初始化两者?
答案 0 :(得分:7)
对于其中一个类,您不在构造函数中提供引用,但您可以使用set
- 方法。当它们之前都不存在时,初始化它们都相互依赖似乎很难。
class Foo {
private Bar bar;
public Foo(Bar bar) {
this.bar = bar;
}
}
class Bar {
private Foo foo;
setFoo(Foo foo) {
this.foo = foo;
}
}
Bar bar = new Bar();
Foo foo = new Foo(bar);
bar.setFoo(foo);
另请注意,可能有更好的解决方案。例如使用Observer-pattern,这一切都取决于您计划如何使用对象。
答案 1 :(得分:5)
你的问题没有多大意义。如果每个类都需要另一个类进行初始化,那么您必须首先重新考虑类的设计方式。
您可能会考虑让其中一个类本身创建另一个类,而不必在构造函数中指定它。例如:
class Class1 {
private Class2 c2;
public Class1() {
this.c2 = new Class2(this);
}
}
class Class2 {
private Class1 c1;
public Class2(Class1 c) {
this.c1 = c;
}
}
或者创建setter并允许它们以“未初始化”状态创建(如果设置不正确,可能会抛出异常)。例如:
class Class1 {
private Class2 c2;
public void setClass2(Class2 c) {
this.c2 = c;
}
public void doSomething() {
if (null == c2) throw new IllegalStateException();
// ...
}
}
class Class2 {
private Class1 c1;
public void setClass1(Class1 c) {
this.c1 = c;
}
public void doSomething() {
if (null == c1) throw new IllegalStateException();
// ...
}
}
// somewhere else....
Class1 c1 = new Class1();
Class2 c2 = new Class2();
c1.setClass2(c2);
c2.setClass1(c1);
此外,如果每个实例需要彼此双链接,您应该检查它们确实由正确的对象拥有,否则您可能会创建错误的引用...这正是它为什么是一个糟糕的设计首先。考虑一下:
Class2 c2 = new Class2(new Class1());
你可能认为它是一个聪明的结构,但是c2.getClass1().getClass2() != c2
。
在上述两种情况下,它都不保证c1.getClass2() == c2 && c2.getClass1() == c1
。
您的课程应该检查后面的参考是否正确,并且您无法使用这两种方法正确实现这一点!
要解决这个鸡和鸡蛋问题,你需要某种工厂方法,或third class。考虑一下:
abstract class Class1 {
public abstract Class2 getClass2();
}
abstract class Class2 {
public abstract Class1 getClass1();
}
public Class3 {
private Class1 c1;
private Class2 c2;
public Class3() {
c1 = new Class1_Impl();
c2 = new Class2_Impl();
}
public Class1 getClass1() { return c1; }
public Class2 getClass2() { return c2; }
private class Class1_Impl extends Class1 {
public Class1 getClass2() { return c2; }
}
private class Class2_Impl extends Class2 {
public Class1 getClass1() { return c1; }
}
}
// and later on...
Class3 c3 = new Class3();
Class1 c1 = c3.getClass1();
Class2 c2 = c3.getClass2();
有了这个,你可以保证c1.getClass2() == c2 && c2.getClass1() == c1
永远。
如果你还在读书,那么你就是在启蒙的轨道上。如果您可以看到此类设计的后果,那么您将了解circular dependency是anti-pattern的方式,应该避免使用。
但是,您的问题不够具体,我无法全面为您提供更合适的方式以更干净,更好的方式解决您的问题。