base类是父类,derived类是子类,首先要 说明的是由于先有父类后有子类,所以生成子类之前要首先有父类。 class是由class的构造函数constructor产生的,每一个class都有构造函数,如果你在编写自己的class时没有编写任何构造函数,那么 编译器为你自动产生一个缺省default构造函数。这个default构造函数实质是空的,其中不包含任何代码。如果父类base class只有缺省构造函数,也就是编译器自动为你产生的。 而子类中也只有缺省构造函数,那么不会产生任何问题,因为当你试图产生 一个子类的实例时,首先要执行子类的构造函数,但是由于子类继承父类, 所以子类的缺省构造函数自动调用父类的缺省构造函数。先产生父类的实例, 然后再产生子类的实例。
示例一:
classbase {
}class derived extendsbase {public static voidmain(String[] args) {
derived d= newderived();
}
}
注:如果父类base class只有缺省构造函数,也就是编译器自动为你产生的。 而子类中也只有缺省构造函数,那么不会产生任何问题,因为当你试图产生 一个子类的实例时,首先要执行子类的构造函数,但是由于子类继承父类, 所以子类的缺省构造函数自动调用父类的缺省构造函数。先产生父类的实例, 然后再产生子类的实例。
示例二:
packagecom.cnblogs.common;public classBase {public static voidsysout(String s) {
System.out.println(s);
}
Base() {
sysout("Base constructor");
}
Base(String param) {
sysout("Base constructor param:" +param);
}
}
packagecom.cnblogs.common;public class Derived extendsBase {
Derived() {//调用父类构造函数(1)
super();//(4)
sysout("derived constructor");
}
Derived(String param) {//调用父类具有相同形参的构造函数(2)
super(param);
sysout("derived constructor param:" +param);
}
Derived(String param1, String param2) {//调用当前具有相同形参的构造函数(3)
this(param1);
sysout("derived constructor param2=:" +param2);
}public static voidmain(String[] args) {
Derived derived= newDerived();
derived= new Derived("参数");
derived= new Derived("参数1", "参数2");
}
}
输出:
Base constructor
derived constructor
Base constructor param:参数
derived constructor param:参数
Base constructor param:参数1
derived constructor param:参数1
derived constructor param2=:参数2
总结:
可见,子类在构造自己时会调用父类相关的构造函数的
super()就调用父类无参的构造函数
super(name) 父类1参数构造函数
this(name) 自己的1参数构造函数
示例三:
packagecom.cnblogs.common;public class Derived extendsBase {
Derived() {//调用父类构造函数(1)//super();//(4)
sysout("derived constructor");
}
Derived(String param) {//调用父类具有相同形参的构造函数(2)//super(param);
sysout("derived constructor param:" +param);
}
Derived(String param1, String param2) {//调用当前具有相同形参的构造函数(3)//this(param1);
sysout("derived constructor param2=:" +param2);
}public static voidmain(String[] args) {
Derived derived= newDerived();
derived= new Derived("参数");
derived= new Derived("参数1", "参数2");
}
}
输出:
Base constructor
derived constructor
Base constructor
derived constructor param:参数
Base constructor
derived constructor param2=:参数2
注: 子类会调用父类无参数构造方法
示例四:
packagecom.cnblogs.common;public classBase {public static voidsysout(String s) {
System.out.println(s);
}//Base() {//sysout("Base constructor");//}Base(String param) {
sysout("Base constructor param:" +param);
}
}
packagecom.cnblogs.common;public class Derived extendsBase {
Derived() {//调用父类构造函数(1)//super();//(4)
sysout("derived constructor");
}
Derived(String param) {//调用父类具有相同形参的构造函数(2)//super(param);
sysout("derived constructor param:" +param);
}
Derived(String param1, String param2) {//调用当前具有相同形参的构造函数(3)//this(param1);
sysout("derived constructor param2=:" +param2);
}public static voidmain(String[] args) {
Derived derived= newDerived();
derived= new Derived("参数");
derived= new Derived("参数1", "参数2");
}
}
注:eclipse会报错。Implicit super constructor Base() is undefined ……说明子类中的构造函数找不到显式写出的父类中的缺省构造函数,所以出错。
示例五:
解决上面问题方法
(1)去掉父类显示的非缺省 构造函数
(2)子类的构造函数调用你显式写出的父类中的缺省 构造函数
packagecom.cnblogs.common;public class Derived extendsBase {
Derived() {//调用父类构造函数(1)//super();//(4)
super("父类有参数构造方法");
sysout("derived constructor");
}
Derived(String param) {//调用父类具有相同形参的构造函数(2)//super(param);
super("父类有参数构造方法");
sysout("derived constructor param:" +param);
}
Derived(String param1, String param2) {//调用当前具有相同形参的构造函数(3)//this(param1);
super("父类有参数构造方法");
sysout("derived constructor param2=:" +param2);
}public static voidmain(String[] args) {
Derived derived= newDerived();
derived= new Derived("参数");
derived= new Derived("参数1", "参数2");
}
}
注:子类如果有多个构造函数的时候,父类要么没有构造函数, 让编译器自动产生,那么在执行子类构造函数之前先执行编 译器自动产生的父类的缺省构造函数;要么至少要有一个显 式的缺省构造函数可以让子类的构造函数调用。
额外备注:
1.子类的构造过程中必须调用父类的构造方法
2.子类可在自己的构造方法中使用super()来调用父类的构造方法
3.如果子类的构造方法中没有显示的调用父类的构造方法,则系统默认的调用父类的无参的构造方法。
4.如果子类的构造方法中既没有显示调用父类的构造方法,而父类中又没有无参的构造方法,则编译出错。