这里是关于Java构造函数被问到问题的总结。
12.1 为什么创建一个子类对象父类的构造函数也会被调用。
class Super {
String s;
public Super() {
System.out.println("Super");
}
}
public class Sub extends Super {
public Sub(){
System.out.println("Sub");
}
public static void main(String[] args){
Sub s = new Sub();
}
}
//它打印:
Super
Sub
当从其他类继承时候,super() 将在构造函数中被第一个调用。如果没有,编译器将插入那个调用。这就是为什么当子类对象创建的时候,父类对象被调用的原因。
它没有创建两个对象,仅仅是一个子类对象被创建。父类构造函数被调用的原因是父类构造函数中也许有一些私有的属性需要通过它的构造函数来初始化。
当编译插入超类的构造函数时候,子类构造函数看起来像下面这样:
Public Sub() {
Super();
System.out.println(“sub”);
}
11.2 隐式的构造函数没有被默认的构造函数定义
这是一个被很多开发者看到的错误信息:
“隐式的父类构造函数没有备定义默认的构造函数,必须定义一个确定的构造函数。”
编译错误发生是因为默认的父类构造函数没有被定义。在java中,如果一个类没有定义一个构造函数,编译器将为这个类插入一个没有参数的默认构造函数。
如果构造函数在父类中被定义了,在这个例子中为super(String s),编译器将不会插入一个默认的无参构造函数。这就是上面父类的情景。
在子类的构造函数中,既有有参的构造函数,又有无参的构造函数,将调用父类无参的构造函数。
当编译器试图在两个子类中插入super()调用两个无参的构造函数时候,但是父类默认构造函数没有被定义,编译器就报了这个错误。
修改这个问题,简单的
1.在父类中添加一个Super()构造函数
Public Super() {
System.out.println(“Super”);
}
或者
2.在父类中删除自己定义的构造函数。
3.在子类构造函数中添加父类构造函数Super(value)的调用。
下面的代码是没问题的
子类的构造函数明确调用了父类的有参构造函数。