首先总结规律:java继承中子类是不会继承父类的构造函数的,只是必须调用(隐式或者显式),因为子类是基于父类产生的。
下面是一段代码:
public class TestDriver{
public static void main(String[] args){
SonClass s=new SonClass(66);
}
}
class FooClass{
public FooClass(){
System.out.println(100);
}
public FooClass(int count){
System.out.println(count);
}
}
class SonClass extends FooClass{
public SonClass(){
}
public SonClass(int c){
System.out.println(1234);
}
}
运行结果:
100 1234
因为子类在生成对象时,优先调用父类的构造方法,而且是其无参的类型。该构造等价于如下形式:
public Sonclass(int c){
super(); //必须在第一行调用,否则不能编译
System.out.println(1234); //在执行这行时系统会优先调用父类的无参构造函数super();
}
接下来介绍另外一种情况(显式调用),如果子类构造函数是这样写的:
public Sonclass(int c){
super(2); //必须写在第一行,否则不能编译,显式调用父类构造函数后,系统就不再默认调用无参构造函数了
System.out.println(1234);
}
运行结果为:
2 1234
说明
- 在java中,创建有参构造函数后,系统就不再有默认的无参构造函数(当然也可以存在无参的版本,但其不再是默认的)
- 如果父类中没有任何构造函数,系统会默认有一个无参的构造函数.
下面来看一道测试题
已知代码:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
问哪句语句会导致错误?()
A、 line 3
B、line 6
C、line 10
D、 line 14
E、 line 15
答案是E。在Java中,如果一个类没有定义构造方法(在constructor方面什么都没做),编译器会默认插入一个无参数的构造方法;但是如果一个构造方法在父类中已定义,在这种情况,编译器是不会自动插入一个默认的无参构造方法。
对于子类来说,不管是无参构造方法还是有参构造方法,都会默认调用父类的无参构造方法,即super(),但可以省略。当编译器尝试在子类中往这两个构造方法插入super()方法时,因为父类没有一个默认的无参构造方法,所以编译器报错。
以上是在原博文里参考的解析,我在eclipse上尝试时显示子类Demo无此构造方法,感觉应该是这个靠谱。
参考资料:
https://www.jianshu.com/p/f7934687e420
https://blog.csdn.net/as091313/article/details/78766191