我无法理解使用带子类的构造函数的概念。
这是父类:
public class A
{
public A()
{
System.out.println("The default constructor of A is invoked");
}
}
儿童班:
public class B extends A
{
public B(String s)
{
System.out.println(s);
}
}
我的主要方法:
public class C
{
public static void main (String[] args)
{
B b = new B("The constructor of B is invoked");
}
}
当我运行C时,我得到的输出是
调用A的默认构造函数
调用B的构造函数
我不明白为什么来自A类的信息正在输出。因为你将一个字符串参数传递给B类的构造函数,所以它不应该打印出来吗?换句话说,输出不应该只是:
调用B的构造函数
在此先感谢,我非常感谢你们给予的任何帮助。
答案 0 :(得分:7)
来自docs
如果构造函数没有显式调用超类构造函数,Java编译器会自动插入对超类的无参数构造函数的调用。如果超类没有无参数构造函数,则会出现编译时错误。对象确实有这样的构造函数,因此如果Object是唯一的超类,则没有问题。
因此,即使您没有显式调用超类构造函数,编译器也会在类super()
的构造函数中插入一个名为B
的语句。
这就是B类构造函数在编译后的样子。
public B(String s){
super(); // this is inserted by the compiler, if you hadn't done it yourself.
System.out.println(s);
}
答案 1 :(得分:4)
编译后class B
-
public class B extends A{
public B(String s){
super();
System.out.println(s);
}
}
为什么!逻辑答案是孩子不能在没有父母的情况下存在,所以父母被快速初始化,然后是孩子。
从技术上讲 - 如果你没有显式调用super class
,那么构造函数编译器会为你做。在你的案件中究竟发生了什么。
如果你明确地调用超类构造函数可以帮助你更仔细地理解它,那么这是一个很好的实验 -
public class B extends A{
public B(String s){
System.out.println(s);
super(); // invoking super later
}
}
您收到编译错误 -
错误:调用super必须是构造函数中的第一个语句
因此,如果您显式调用超类构造函数,则必须在构造函数的开头调用,这应该是第一个语句。
答案 2 :(得分:0)
它这样做的原因是,如果B确实是A的子类,B需要包含A中的所有字段。因此,当您调用构造函数时
B b = new B("The constructor of B is invoked");
它调用A的默认构造函数来初始化A的字段,因此B实际上是逻辑上的
public class B extends A
{
public B(String s)
{
super();
System.out.println(s);
}
}
super只调用A的默认构造函数。如果编译器没有这样做,那么你将在B中继承未初始化的字段,因为它继承自A!