super关键字在Java中的使用

super关键字在Java中的使用,java,inheritance,super,Java,Inheritance,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() {

即使在子类中没有使用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的构造函数

一,

二,


我无法理解为什么我的控制台上会打印A的构造函数?

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


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

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


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

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


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

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


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

检查以下行


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


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

我希望,这能消除你的疑虑

[更新]

发布此更新以澄清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();
    }
}

从中检查以下行


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


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

我希望,这能消除你的疑虑

[更新]

发布此更新以澄清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();
    }
}

这就是java的工作原理。这主要是为了在创建子对象之前初始化父对象属性,以维护具有一致状态的子对象。子对象不能在其父对象之前存在。
super()
由编译器自动添加我认为super关键字用于调用父类构造函数,但如果自动调用父类构造函数,那么super()关键字有什么用?@NikhilBansal您只能避免wri