1

想不出更好的标题。

一个经典的学习示例: class 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()我应该用所有参数调用构造函数,但我不确定它是否正确以及唯一可用的选项。

将不胜感激这里的任何指导。

4

5 回答 5

4

是的,你对它发生的原因是正确的。不过可以肯定的是:

  • new Human()来电this("Jack", 22)
  • this("Jack", 22)来电this(age, name, new Human())
  • 再次new Human()调用的inthis("Jack", 22)
  • this(age, name, new Human())再次调用
  • 直到你用完堆栈

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

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

当然,这意味着新实例将具有nullfor mother

于 2019-07-20T11:32:37.280 回答
1

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

  1. 在Java 语言中(使用构造函数)有不同的方法吗?
  2. 在面向对象设计中有更好的方法吗?

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

关于第二个问题,一个流行的解决方案是simple factory模式,你只有一个带有所有参数的私有构造函数,然后是一些公共工厂方法来做你想做的任何事情。

于 2019-07-20T11:41:37.190 回答
0

您的构造函数Human(int, String)在没有任何条件的情况下进行递归,最后创建一个StackOverflowError.

构造函数重载是提供创建对象的便捷方式的一种非常常见的方式。只要成员不是final并且以后可能会被操纵,您最好不传递任何值(aka null),而不是动态创建更多对象。

实际上,没有母亲就没有人类,但它可能是未知的,所以null现在通过将是更好的方法。

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

于 2019-07-20T11:47:16.797 回答
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;
}

这不会创建任何 hirarical 或嵌套构造函数

于 2019-07-20T11:39:18.317 回答
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 实例创建为人类,然后在孩子中设置为人类。让我知道更具体的答案。

于 2019-07-20T12:01:14.930 回答