public class Base {
public Base() {
foo();
}
public void foo() {
System.out.println("Base.foo()");
}
}
public class Derived extends Base {
public Derived () {}
public void foo() {
System.out.println("Derived.foo()");
}
}
然后,当我打电话给那些人时:
public class Running {
public static void main(String[] args) {
Base b = new Base();
Derived d = new Derived();
}
}
输出:
*Base.foo()*
*Derived.foo()*
那么为什么当它到达派生构造函数时,它会调用基础构造函数,而是使用派生的方法呢?
PS:如果我将这些方法标记为私有,则会打印出来:
*Base.foo()*
*Base.foo()*
答案 0 :(得分:2)
这就是Java的工作原理,请阅读此页面https://docs.oracle.com/javase/tutorial/java/IandI/super.html
更具体地说,这里的注释:
注意:如果构造函数没有显式调用超类 构造函数,Java编译器自动插入一个调用 超类的无参数构造函数。如果超级班没有 有一个无参数的构造函数,你会得到一个编译时错误。 对象确实有这样的构造函数,所以如果Object是唯一的 超类,没有问题。
因此,您可以看到这是预期的行为。即使你有一个超级呼叫,它仍然会自动插入它。
关于第二个问题,即使你在超级构造函数体内仍然是Instance属于Subtype。如果您对C ++有一定的了解,请阅读此Can you write virtual functions / methods in Java?
在使用private标记时它将写入基类的原因是私有方法不是Inherited。这是Java继承主题的一部分。
答案 1 :(得分:1)
回答标题中的问题。正如我所说,你无法避免被调用的基类构造函数(或者如果它有多个基类构造函数之一)。您当然可以轻松避免正在执行的构造函数的主体。例如:
public class Base {
public Base(boolean executeConstructorBody) {
if (executeConstructorBody) {
foo();
}
}
public void foo() {
System.out.println("Base.foo()");
}
}
public class Derived extends Base {
public Derived() {
super(false);
}
public void foo() {
System.out.println("Derived.foo()");
}
}
public class Running {
public static void main(String[] args) {
Base b = new Base(true);
Derived d = new Derived();
}
}
现在主要方法仅打印:
Base.foo()
答案 2 :(得分:0)
因为在Derived类的构造函数中,如果你没有向super或同一个类中的其他构造函数添加调用(使用它),它会自动注入对super()的调用。