首先我们要知道构造方法是类的一个特殊成员,它会在类实例化对象时被自动调用
子类中,它在调用父类中空参数的构造函数。因为子类继承父类,会继承到父类中的数据,所以必须要看父类是如何对自己的数据进行初始化的。所以子类在进行对象初始化时,先调用父类的构造函数,这就是子类的实例化过程
定义一个Dog类继承自Animal类
Animal类中有一个有参构造方法,传入变量 name
public class Animal {
public Animal(String name){ // 有参构造方法
System.out.println("我是一只"+name);
}
}
public class Dog extends Animal {
// 继承自Animal类
public Dog(){
super("沙皮狗"); // 调用父类有参的构造方法 // 1
}
}
public static void main(String[] args) {
// 实例化子类Dog对象
Dog dog=new Dog();
}
}
运行结果为:
通过结果可以看出 通过super调用父类的构造方法 在子类对象初始化时候调用了父类的构造方法。
如果把Dog类中构造方法的 1 处 super("沙皮狗") 这行代码去掉。
程序提示出错。运行结果是
implicit 含义为隐式 explicit含义为显式 invoke 调用
这行语句大致意思是: 隐式的 super 构造函数Animal()是未定义的。必须显式调用另一个构造函数(即调用有参的构造方法)
进一步理解。因为Dog类继承自Animal类。当初始化Dog对象时会调用父类Animal的构造方法。
我们可以在子类的构造方法中通过super指定调用父类的哪个构造方法。如果没有指定。在实例化子类对象时候会自动调用父类无参的构造方法。
然而父类Animal中只有有参的构造方法。
在Java中的每个类都至少有一个构造方法,如果在一个类中没有定义构造方法,系统会自动为这个类创建一个默认的构造方法。这个默认方法没有参数,在其方法体中也没有任何代码。即什么也不做。
但是如果一旦为该类定义了构造方法。系统就不再提供默认的构造方法了
因此。由于Dog类中构造方法的 1 处 super("沙皮狗") 代码没有了 。而父类又没无参的构造方法。所以程序出错。
为了解决上述编译问题。
1、可以在子类中显式的调用父类中已有的构造方法,
2、也可以在父类中定义无参的构造方法
如果父类的构造方法是带参数的,而且没有无参数的构造方法,那么在子类的构造方法中必须显式地调用父类的构造方法。
如果父类的构造方法是无参数的,那么在子类中写不写都可以,不写的话会隐式地调用。