Java 为什么我的子类构造函数没有被调用?
我有这样的继承结构:Java 为什么我的子类构造函数没有被调用?,java,inheritance,constructor,Java,Inheritance,Constructor,我有这样的继承结构: public abstract class Mom { int dummy; Mom() { dummy = 0; } Mom(int d) { this(); dummy = d; } } public class Kid extends Mom { String foo; Kid() { super(); foo = ""; }
public abstract class Mom {
int dummy;
Mom() {
dummy = 0;
}
Mom(int d) {
this();
dummy = d;
}
}
public class Kid extends Mom {
String foo;
Kid() {
super();
foo = "";
}
Kid(int d) {
super(d);
}
}
// ...
Kid kiddo = new Kid(10);
// kiddo.foo == null !
我的Kid
的无参数构造函数从未被调用!以下是我所期望的:
新生儿(10)
→ <代码>儿童#儿童(智力)super(d)
→ <代码>妈妈#妈妈(int)this()
→ Kid#Kid()
//doh李>
super()
→ <代码>妈妈#妈妈()Mom
调用Kid
的无参数构造函数吗?我想不是,我将添加一个抽象方法[1]
init()
,它将调用Mom
,而Kid
s必须重写。但我只是想知道确切的原因,如果可能的话,举例说明为什么要调用子类的构造函数是个坏主意(即使子类的构造函数确实调用了
super()
)
我会安排这些,这样你就不需要调用每个构造函数
public abstract class Parent {
final int dummy;
Parent () {
this(0);
}
Parent (int d) {
dummy = d;
}
}
public class Kid extends Parent {
final String foo = "";
Kid() {
}
Kid(int d) {
super(d);
}
}
使用final
确保每个字段设置一次
从构造函数调用任何可重写的方法被认为是不好的做法,因此让构造函数重写是一个坏主意
this()
调用同一类的构造函数,因为构造函数不遵循继承(静态方法也不遵循继承)
构造函数会这样做,否则多次调用同一个构造函数会有危险,并且无法保证最终方法只设置一次。您应该为Kid类设置这些构造函数:
Kid(int i) {
super(i);
whatever();
}
Kid () {
this( DEFAULT_VALUE);
}
所以所有对父构造函数的调用都是通过子类的完全限定构造函数进行的。类的所有构造函数都有一个默认行为,它不会像当前代码那样被绕过。来自(我强调):
- 替代构造函数调用以关键字
开始(可能以显式类型参数开头)他们已经习惯了 调用同一类的备用构造函数。this
- 超类构造函数调用以关键字
(可能以显式类型参数开头)或主 表情它们用于调用直接 超类。super
foo=”“代码>。这也称为字段初始值设定项
{foo=”“;}
。注意,如果类中需要,可以有多个实例初始值设定项如果同一字段也在构造函数中初始化,那么构造函数将获胜。是的,
Kid
确实扩展了Mom
我可能还需要在Mom
和Dad
之间添加一个接口。我知道这是一个不好的做法,但是,我的init
方法的目的是将成员字段设置为其默认值。我的类非常简单,我确信在子类方法尚未完全构造时调用它不会失败。不过,如果你有更好的设计想法,我就要了!非常感谢。更改了我答案中的示例,因此每个字段都设置了一次且仅设置了一次。哦,我明白了。谢谢你的详细回答。那么我将使用选项1!-但是如果我初始化foo=“init”
然后使用实例初始化器创建一个对象,该实例初始化器将foo
初始化为另一个值。在这种情况下,谁赢了?@Bicou我已经扩展了我的答案来回应这一评论。这是一种从左到右(或从上到下)的逻辑,因此最后一次初始化获胜。
new Kid(10) --> Kid#Kid(int)
super(d) --> Mom#Mom(int)
this() --> Mom#Mom()
Kid(int i) {
super(i);
whatever();
}
Kid () {
this( DEFAULT_VALUE);
}