子类构造函数 - 为什么子类构造函数必须存在默认构造函数?

时间:2012-02-21 00:35:53

标签: java constructor subclass

给出一个随机类:

public class A<T> {
    public T t;

    public A () {}  // <-- why is this constructor necessary for B?
    public A (T t) {
        this.setT(t);
    }
    public T getT () {
        return this.t;
    }
    protected void setT (T t) {
        this.t = t;
        return;
    }
}

扩展课程:

public class B extends A<Integer> {
    public B (Integer i) {
        this.setT(i);
    }
}

为什么B要求A拥有空构造函数?我原以为它会想要使用类似的构造函数而不是默认的构造函数。我尝试在没有默认构造函数的情况下进行编译,但是没有它我得到以下消息......

java.lang.NoSuchMethodError: A: method <init>()V not found at B.<init>

任何人都可以解释为什么会这样吗?

3 个答案:

答案 0 :(得分:10)

重要的是要理解任何构造函数的第一行是调用超级构造函数。如果您没有自己调用超级构造函数,编译器会在封面下插入super()来缩短代码。

此外,如果您没有任何构造函数,则会自动插入一个空的默认构造函数 - 此处为A()B()

您的B构造函数中没有super(...),因此编译器会自行插入super()调用,但您有A - 带有参数的构造函数,因此未插入默认的A() - 构造函数,您必须手动提供A() - 构造函数,或者调用A(i) - 构造函数。在这种情况下,我建议只有

public class B extends A<Integer> {
    public B (Integer i) {
        super(i);
    }
}

答案 1 :(得分:6)

您可以在A中使用自己的构造函数,但必须从B的构造函数中明确地调用它,例如:

public B(Integer i) {
  super(i);
  ...
}

如果不这样做,编译器将尝试通过调用其默认构造函数来实例化A本身。

答案 2 :(得分:2)

如果你没有使用super(i)作为构造函数的第一行调用超级构造函数,它将隐式调用默认的超级构造函数