我有这两个类:
public class Document {
private static int quantity = 0;
public Document() {
quantity = quantity + 1;
}
public static int getQuantity() {
return quantity;
}
}
public class Book extends Document {
private int numChapters;
public Book(int numChapters) {
this.numChapters = numChapters;
}
public static void main(String[] args) {
Book b1 = new Book(4);
Book b2 = new Book(6);
Document d1 = new Document();
System.out.println(Document.getQuantity());
}
}
这里的程序返回3,但我希望它返回1.有人可以告诉我代码中发生了什么吗?似乎在创建b1和b2时隐式调用父类的构造函数。据我所知,子类不会继承其父类的构造函数。
答案 0 :(得分:4)
请参阅docs:
注意:如果构造函数没有显式调用超类 构造函数,Java编译器自动插入一个调用 超类的无参数构造函数。如果超级班没有 有一个无参数的构造函数,你会得到一个编译时错误。 对象确实有这样的构造函数,所以如果Object是唯一的 超类,没有问题。
你有一个自动调用的无参数构造函数。
这种行为很有意义,构造函数用于创建对象。所以它应该包含适合其类的初始化代码。如果你的班级扩展另一个怎么办?它不应该包含构造该对象所需的所有代码吗?
答案 1 :(得分:0)
子类必须调用其超类的构造函数,即使子类的构造函数没有显式调用super()
。实际上,如果编译器找不到它可以从子类的构造函数调用的超类构造函数,则代码将无法编译。
答案 2 :(得分:0)
在创建b1和b2时,似乎隐式调用了父类的构造函数。
这是正确的。
据我所知,子类不继承其父类的构造函数。
这也是正确的。但是,它并不意味着不调用超类构造函数。
在Java中,当使用new
(或反射等价物)创建对象 1 时,无论您是否进行super(...)
调用,都会调用超类构造函数在子类构造函数中。
1 - 对于记录,当通过对象反序列化创建实例时,不会调用任何构造函数。对象的再创造是通过一些幕后黑魔法完成的,这使得对象不会调用它的构造函数。