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

时间:2012-10-15 07:31:50

标签: java inheritance constructor

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

C

不应该是:

A

A

C

因为超级关键字

5 个答案:

答案 0 :(得分:8)

如果您未明确指定,

super();始终存在。如果您没有明确指定,Java只会添加自动调用。

所以你的代码

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

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

答案 1 :(得分:4)

没有。如果您在构造函数中调用super,则不会添加自动调用。如果您将自己的电话留出,编译器只会添加自动呼叫。因此super();中的b行是不必要的,因为这正是编译器将为您添加的(调用默认构造函数)。也就是说,这两位源产生相同的字节码:

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

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

能够直接调用超类构造函数的原因是为了向它传递参数,因为编译器只会向默认构造函数添加调用(并且如果超类上没有调用,则会抱怨)。 p>

答案 2 :(得分:2)

super();在任何构造函数中通过继承树被称为一次,要么是显式执行,要么是隐式执行。所以你不应该期待" A"将被打印两次。

这不会编译:

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

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

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

答案 3 :(得分:0)

如果使用extends关键字创建其他类的子类,则java编译器将 super()调用作为构造函数的第一行(如果您自己没有这样做)。 在您的示例中,类 a 扩展(默认情况下) java.lang.Object(),编译后第一行是调用 super()调用 Object 默认构造函数。 在运行子类构造函数中的代码之前,运行其超类构造函数中的代码。

为什么 A 不会多次打印?因为只有你自己没有这样做,Java编译器才会在构造函数的开头添加 super()。 (例如,您可能希望调用带有一些参数的超类构造函数)

希望能澄清一点。

答案 4 :(得分: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();
    }
}