在 Java 中使用 super 关键字

Use of super keyword in Java

我对打印超类构造函数语句有疑问,即使我没有在子类中使用 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's constructor

1

2

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

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

即使在您的构造函数的任何部分中不可视地调用 super(),Java 本身也会调用 class A 的构造函数。

如果构造函数没有显式调用超类构造函数,Java 编译器会自动插入对超类的无参数构造函数的调用。如果超类没有无参数构造函数,您将收到编译时错误。 Object确实有这样一个构造函数,所以如果Object是唯一的父类,没有问题。

换句话说,构造函数 B(int a , int b) 隐式调用构造函数 A() 。在 IDE 中,只需将 A() 更改为 A(int i),您就会看到构造函数 B(int a , int b) 的错误消息,例如 "Implicit super constructor A() is undefined. Must explicitly invoke another constructor".

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

中的以下行

Note: If a constructor does not explicitly invoke a superclass constructor, the Java compiler automatically inserts a call to the no-argument constructor of the superclass. If the super class does not have a no-argument constructor, you will get a compile-time error. Object does have such a constructor, so if Object is the only superclass, there is no problem.


If a subclass constructor invokes a constructor of its superclass, either explicitly or implicitly, you might think that there will be a whole chain of constructors called, all the way back to the constructor of Object. In fact, this is the case. It is called constructor chaining, and you need to be aware of it when there is a long line of class descent.

我希望,它消除了你的疑虑。

[更新]

发布此更新以消除 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 构造函数调用它。

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();
    }
}