我们都知道如果初始化一个子类,一定会先初始化父类,即调用父类的构造方法,再调用子类的构造方法,但是如果父类有很多的构造方法,那么调用哪一个呢?看下面的例子:
package io; public class ConstructorTest { public static void main(String[] args) { // TODO Auto-generated method stub B b = new B(100); //B b = new B(); } } class A { public A() { System.out.println("A no params"); } public A(int i) { System.out.println("A has params"); } } class B extends A{ public B(){ System.out.println("B no param"); } public B(int i) { System.out.println("B has params"); } }
output:
A no params B has params
可以看到调用了父类的默认构造方法,为了验证如果将A的无参数的构造方法注释掉,则new B的时候会报错,
class A { /*public A() { System.out.println("A no params"); } */ public A(int i) { System.out.println("A has params"); } }
Implicit super constructor A() is undefined. Must explicitly invoke another constructor
而如果这时候将A的两个构造方法都注释掉,却又不报错了:
class A { /*public A() { System.out.println("A no params"); } */ /*public A(int i) { System.out.println("A has params"); }*/ }
这是因为如果A中没有构造方法,那么会默认给它创建一个无参数的构造方法。而如果有其它的构造方法了,就不会给它创建了。所以说子类默认调用的是父类的无参数的构造方法,或者当父类确实没有无参数的构造方法时,还可以通过super来调用它的其它构造方法:
class A { /*public A() { System.out.println("A no params"); } */ public A(int i) { System.out.println("A has params"); } } class B extends A{ public B(){ super(21); System.out.println("B no param"); } public B(int i) { super(i); System.out.println("B has params"); } }
注意:如果要显式的调用super,那么必须把它放在第一位。如果不放在第一位,那么super之前的初始化语句等于是没有执行,因为在super中还得重新初始化,这显然不符合情理、