在超类和基类的构造函数中的调用层次结构

3
class a
{
a(){System.out.println("A");}
}

class b extends a
{
b()
{
super();
System.out.println("B");}
}

class c extends b
{
c(){System.out.println("c");}
}

class last
{
public static void main(String aaa[])
{
c obj = new c();
}
}

输出结果如下:

A

B

C

不应该是这样的:

A

A

B

C

因为有super关键字。
5个回答

8

super();总是存在的,如果您没有明确指定。Java只有在您没有明确指定时才会添加自动调用。

因此,您的代码:

    B() {
        super();
        System.out.println("B");
    }

相同
    B() {
        System.out.println("B");
    }

4

不需要。如果你在构造函数中调用了super,那么自动调用就不会被添加。只有当你省略的时候,编译器才会添加自动调用。所以,在b中的super();行是没必要的,因为这正是编译器将为你添加的(调用默认构造函数)。也就是说,这两个源代码位产生相同的字节码:

// This
class b {
    b() {
    }
}

// Results in the same bytecode as this
class b {
    b() {
        super();
    }
}

能够直接调用超类构造函数的原因是为了向其中传递参数,因为编译器只会添加对默认构造函数的调用(如果超类没有默认构造函数,则编译器将报错)。

2

super(); 在继承树中的任何构造函数中仅被调用一次,无论是您显式调用还是隐式调用。因此,您不应该期望"A"会被打印两次。

以下代码将无法编译:

b()
{
    super();
    super();
    System.out.println("B");
}

错误信息:构造函数必须是构造函数中的第一个语句。

这意味着您不允许在构造函数中多次调用super()


0
package threaddemo;

public class NewClass {
    NewClass() {
        System.out.println("hello");
    }
}

class Child extends NewClass {

    Child() {
        System.out.println("child");
    }

    public static void main(String []ar) {
        Child c1=new Child();
    }
}

1
如果您传递参数,必须使用super。 - Kultaran Singh

0
如果你创建了另一个类的子类,使用扩展关键字,那么Java编译器会将super()调用放在构造函数的第一行(如果您自己没有这样做)。 在您的示例中,类a默认扩展java.lang.Object(),编译后的第一行是调用super(),它调用Object默认构造函数。 因此,在运行子类构造函数中的代码之前,会先运行其超类构造函数中的代码。
为什么A不会被多次打印? 因为Java编译器仅在您没有自己添加时,才会在构造函数开头添加super()。(例如,您可能想调用需要传入某些参数的超类构造函数)
希望这能解释清楚一些事情。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接