Java中的链构造函数

时间:2019-07-20 11:26:33

标签: java constructor-overloading constructor-chaining

无法提出更好的标题。

一个经典的学习示例:类Human,其中属性是姓名,年龄,母亲和父亲。父母双方也是Human

public class Human {
    String name;
    int age;
    Human mother;
}

我想创建3个构造函数:

  1. Human();
  2. Human(String name, int age);
  3. Human(String name, int age, Human mother)

猜测,我确实了解链接的工作原理,这就是我所做的:

Human() {
    this("Jack", 22);
}

Human(int age, String name) {
    this(age, name, new Human()); // new Human() will cause SOF Error.
}

Human(int age, String name, Human mother) {
    this.age = age;
    this.name = name;
    this.mother = mother;
}

如上所述,我收到StackOverflowError,我再次猜测,我知道它为什么发生。 虽然公平地说,我想我会得到像人类杰克这样的东西,而他的母亲也是人类杰克

尽管如此,我不知道应该怎么做。我的猜测是,我应该使用所有参数而不是new Human()来调用构造函数,但是我不确定它是否为真并且是唯一可用的选项。

在这里感谢您的任何指导。

5 个答案:

答案 0 :(得分:5)

是的,您对它为什么会发生是正确的。不过,请确保:

  • new Human()呼叫this("Jack", 22)
  • this("Jack", 22)呼叫this(age, name, new Human())
  • 其中的new Human()再次调用this("Jack", 22)
  • 再次调用this(age, name, new Human())
  • 直到堆栈用完

正确的方法是确保您不会回到起点。因此,如果您在任何构造函数中使用new Human(String)new Human(String, int),则必须确保该构造函数(new Human(String)new Human(String, int))也不要使用{{1 }}或new Human(String),因为您将无休止地递归。您需要在某处使用new Human(String, int)。例如:

new Human(String, int, Human)

当然,这意味着新实例将为Human(int age, String name) { this(age, name, null); } 使用null

答案 1 :(得分:1)

如果我正确理解了您的问题,则有两个子问题:

  1. 使用 Java语言(带有构造函数)是否有其他方法?
  2. 在面向对象设计中是否有更好的方法?

关于第一个问题,构造函数是一个方法,您的实现产生两个递归方法。您必须中断递归或引入退出条件。 还有另一种选择-在第一个构造函数中调用this(age, name, null)

关于第二个问题,一个流行的解决方案是simple factory模式,其中只有一个带有所有参数的 private 构造函数,然后有一些公共工厂方法可以执行您想要的任何操作

答案 2 :(得分:0)

Human() {
    this.name = "Jack";
    this.age = 22;
}

Human(int age, String name) {
    this.age = age;
    this.name = name;
    this.mother = null;
}

Human(int age, String name, Human mother) {
    this.age = age;
    this.name = name;
    this.mother = mother;
}

这将不会创建任何函数式或嵌套的构造函数

答案 3 :(得分:0)

您的构造函数Human(int, String)进行没有任何条件的递归,最终创建了StackOverflowError

构造函数重载是提供创建对象的便捷方法的一种非常常见的方法。只要成员不是final并且以后可以进行操作,则最好不要传递任何值(也称为null),而不是动态创建更多对象。

实际上,没有人没有母亲,但是没有人知道,因此现在通过null会是更好的方法。

如果您需要不可变的 mother ,则不得在没有参考的情况下为母亲提供任何构造函数,以使其清晰可见。即使这样也行不通,因为您无法为人类的起源提供如此无尽的树形结构。通常,此类结构具有一个“根”对象,该对象没有父对象(在此示例中为 mother )。

答案 4 :(得分:0)

我建议不要去构造函数链接。我更喜欢例如变量链接,并使用构建器设计模式以及节点类型的数据结构。

Class Human{
int age;
Sting name;
Human mother;

public  Human setAge(int age){
this.age = age;    
return this;
}

public Human setName(String name){
this.name = name;
return this;
}

public Human setHuman(Human mother){
this.mother= mother;
return this;
}

}

完成此操作后,您可以将第一个Mother实例创建为人类,然后在孩子中将其设置为人类。让我知道更具体的答案。