我做了以下操作,一段时间后我遇到了stackoverflow错误,我明白为什么会这样。
public class Cat {
String name="default name";
Cat insideCat;
public Cat(){
System.out.println("Cat constructor");
insideCat = new Cat();
}
}
但是如果我不在构造函数中创建一个新的Cat对象,但是接受Cat类型的参数并将其分配给insideCat字段。
public class Cat {
String name="default name";
Cat insideCat;
public Cat(Cat insideCat){
System.out.println("Cat constructor");
this.insideCat = insideCat;
}
}
我只是在玩代码,只是试图找出Java可以做什么,不能做什么。在第二个代码中,一切看起来都很正常,直到我开始测试这个类。我需要一个Cat对象来创建一个Cat对象(并创建这个Cat对象,我需要另一个Cat对象......然后它继续)。所以从技术上讲,我无法测试这门课程。
所以我的问题是为什么java允许创建自己类型的实例变量?我想构造函数的全部目的是初始化它的实例变量。所以要么我必须创建一个新对象来初始化insideCat,否则我必须从外面获取Cat对象。两者似乎都不起作用。
我在这里缺少什么。是否存在其自身类型的实例变量可以变得有用的情况,并且可以毫无问题地使用?想出这样的课程是不是OOP练习不好?
答案 0 :(得分:11)
这样的课程一直存在。
考虑链接列表或树,例如,
class ListNode {
ListNode next;
// Etc.
}
class TreeNode {
TreeNode left;
TreeNode right;
// Etc.
}
你不会初始化"孩子"在构造函数中,您可以在以后添加它们。
在您的示例中,您需要拥有一个稍后创建insideCat
的方法。一般情况下,你不会创建具有完全相同状态的子对象,在构造时可以区分它们,在这种情况下,你可以有一个"哦,上帝现在停止创建这些对象和"哦#34;条件,或者在添加它们时,例如,您通过方法而不是在构造函数中添加它们。
答案 1 :(得分:2)
拥有同一个类的实例成员没有任何问题。 员工有经理,经理也是员工
public class Employee{
private Employee manager;
//getters setters and constructor
}
答案 2 :(得分:1)
有很多自引用数据结构的例子是有效的。想想LinkedList
。每个LinkNode
都有一个数据字段和一个指向下一个LinkNode
的指针。
class LinkNode {
int data;
LinkNode nextLink;
public LinkNode(int d1) {
data = d1;
nextLink = null;
}
...
}
class LinkedList {
private LinkNode first;
...
}
您的StackOverflow
问题源于这样一个事实:创建一个而不是X
需要创建另一个X ,
无限广告。
想想你的Cat
例子。为什么要实例化猫需要所有东西......另一个Cat
!
答案 3 :(得分:1)
可以有多个构造函数。因此,您可以拥有另一个构造函数
public Cat(){...}
这将允许您创建内部Cat。然后你可以创建另一个包含内部Cat的Cat。显然,根据您的需要,这里的设计可能不太好。 Dave Newton关于链表的答案是这种用法的一个很好的现实世界的例子。