Java中super关键字的使用



即使我没有在子类中使用super((关键字,我也对打印超类构造函数语句表示怀疑。

class A
{
int i;
A()
{
System.out.println("A's constructor");
}
}
class B extends A
{
int i;
B(int a , int b)
{
super.i=a;
i=b;
}
void show()
{
System.out.println(super.i);
System.out.println(i);
}
}
class UseSuper
{
public static void main(String[] args)
{
B b=new B(1,2);
b.show();
}
}

我的程序的输出是:

A的构造函数

1

2

我不明白为什么要在控制台上打印A的构造函数?

检查https://docs.oracle.com/javase/tutorial/java/IandI/super.html


注意:如果构造函数没有显式调用超类构造函数,Java编译器会自动插入对没有超类的参数构造函数。如果超级类没有如果有一个无参数构造函数,则会出现编译时错误。对象确实有这样的构造函数,所以如果Object是超类,没有问题。


如果子类构造函数调用其超类的构造函数,无论是明确的还是隐含的,你可能会认为调用了整个构造函数链,一直返回到对象的构造函数。事实上,情况就是这样。它被称为构造函数链接,并且当存在阶级血统的长队。

我希望它能消除你的疑虑。

[更新]

发布这一更新是为了澄清OP在以下评论中提到的疑虑。

以下代码不会编译,因为隐式超级构造函数A()尚未定义,我们也未显式定义它。请注意,当没有定义带参数的其他构造函数时,会自动定义隐式超级构造函数A()

class A {
int i;
A(int x,int y){
}
}
class B extends A {
int i;
B(int a, int b) {
super.i = a;
i = b;
}
void show() {
System.out.println(super.i);
System.out.println(i);
}
}
public class UseSuper {
public static void main(String[] args) {
B b = new B(1, 2);
b.show();
}
}

[另一次更新]

发布这一更新是为了澄清OP在下面的评论中提到的另一个疑问。

以下代码也不会编译,因为超级构造函数A()已声明为private,阻止子类构造函数调用它。

class A {
int i;
private A() {
System.out.println("A's constructor");
}
}
class B extends A {
int i;
B(int a, int b) {
super.i = a;
i = b;
}
void show() {
System.out.println(super.i);
System.out.println(i);
}
}
class UseSuper {
public static void main(String[] args) {
B b = new B(1, 2);
b.show();
}
}

当一个类扩展另一个类时,在调用当前类的构造函数之前,首先调用父类的构造函数并初始化它是至关重要的。

即使在构造函数的任何部分都没有可视化地调用super(),Java本身也会调用类A的构造函数。

如果构造函数没有显式调用超类构造函数,Java编译器会自动插入对该超类的无参数构造函数的调用。如果超类没有无参数构造函数,则会出现编译时错误。对象确实有这样的构造函数,所以如果Object是唯一的超类,就没有问题。

换句话说,构造函数B(int a,int B(隐式调用构造函数a((。在IDE中,只需将A((更改为A(int i(,您就会看到构造函数B(int A,int B(的错误消息,如"隐式超级构造函数A((未定义。必须显式调用另一个构造函数"。

最新更新