我有一些java代码:
class Protected{
int n = 1;
public Protected(){
System.out.println("Constructor of protected");
System.out.println("========================");
System.out.println("n = "+n);
System.out.println();
}
}
class Derived extends Protected{
Derived(){
System.out.println("Constructor of derived");
System.out.println("======================");
System.out.println("n = "+(n+1));
}
}
public class Demo{
public static void main(String args[]){
Derived ob2 = new Derived();
}
}
我的输出为:
constructor of protected
========================
n=1
constructor of Derived
========================
n=2
这就是我想要的:
constructor of Derived
========================
n=2
答案 0 :(得分:7)
必须为子类的每个新实例调用超类构造函数。如果您没有在子类构造函数中提供对超类构造函数的显式调用,那么Java将插入对无参数超类构造函数的隐式调用。这解释了为什么你会看到超类构造函数的输出。
要删除该输出,您可以执行以下操作之一:
1)从超类构造函数中删除输出语句。
2)在超类中创建另一个不输出任何内容的构造函数,并在子类构造函数中显式调用它。
如果构造函数体不是以显式构造函数调用开始并且声明的构造函数不是原始类Object的一部分,那么构造函数体隐式地以超类构造函数调用“super();”开头,调用它的直接超类的构造函数,不带参数。
答案 1 :(得分:1)
这是隐式发生的事情:
class Derived extends Protected{
Derived(){
super(); // <--- This is called whether you want to or not
System.out.println("Constructor of derived");
System.out.println("======================");
System.out.println("n = "+(n+1));
}
在Java中绝对没有办法做到这一点;它会破坏语言规范。如果不需要打印,请不要在基类中放置print语句。
JLS 12 Execution / 12.5 Creation of New Class Instances
在作为结果返回对新创建的对象的引用之前,处理指示的构造函数以使用以下过程初始化新对象:
- 为构造函数[...]
分配参数- 如果此构造函数以同一个类中的另一个构造函数的显式构造函数调用开始(使用
this
),那么[...]- 此构造函数不以同一个类中另一个构造函数的显式构造函数调用开始(使用
this
)。 如果此构造函数用于Object
,以外的类,则此构造函数将以显式或隐式调用超类构造函数开始(使用{{1} })。- 为此类[...]
执行实例初始值设定项和实例变量初始值设定项- 执行此构造函数的其余部分[...]
醇>
答案 2 :(得分:0)
您不应该扩展超类以获得所需的输出。或者您可以在Super类中定义另一个重载的构造函数,并且需要在子类构造函数中显式调用它。
当一个子类构造函数被调用时,在构造函数的主体执行之前,将调用超类构造函数,因此你的程序输出。