java中constructor,类继承中构造方法的继承问题
摘要: http://blog.csdn.net/zgzhjj001/article/details/2247983
http://blog.csdn.net/ap0406708/article/details/4002973
base类是父类,derived类是子类,首先要 说明的是由于先有父类后有子类,所以生成子类之前要首先有父类。 class是由class的构造函数constructor产生的,每一个class都有构造函数,如果你在编写自己的class时没有编写任何构造函数,那么 编译器为你自动产生一个缺省default构造函数。这个default构造函数实质是空的,其中不包含任何代码。如果父类base class只有缺省构造函数,也就是编译器自动为你产生的。 而子类中也只有缺省构造函数,那么不会产生任何问题,因为当你试图产生 一个子类的实例时,首先要执行子类的构造函数,但是由于子类继承父类, 所以子类的缺省构造函数自动调用父类的缺省构造函数。先产生父类的实例, 然后再产生子类的实例。
示例一:
class base { } class derived extends base { public static void main(String[] args) { derived d = new derived(); } }
注:如果父类base class只有缺省构造函数,也就是编译器自动为你产生的。 而子类中也只有缺省构造函数,那么不会产生任何问题,因为当你试图产生 一个子类的实例时,首先要执行子类的构造函数,但是由于子类继承父类, 所以子类的缺省构造函数自动调用父类的缺省构造函数。先产生父类的实例, 然后再产生子类的实例。
示例二:
package com.cnblogs.common; public class Base { public static void sysout(String s) { System.out.println(s); } Base() { sysout("Base constructor"); } Base(String param) { sysout("Base constructor param:" + param); } }
package com.cnblogs.common; public class Derived extends Base { 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 void main(String[] args) { Derived derived = new Derived(); 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参数构造函数
示例三:
package com.cnblogs.common; public class Derived extends Base { 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 void main(String[] args) { Derived derived = new Derived(); derived = new Derived("参数"); derived = new Derived("参数1", "参数2"); } }
输出:
Base constructor
derived constructor
Base constructor
derived constructor param:参数
Base constructor
derived constructor param2=:参数2
注: 子类会调用父类无参数构造方法
示例四:
package com.cnblogs.common; public class Base { public static void sysout(String s) { System.out.println(s); } // Base() { // sysout("Base constructor"); // } Base(String param) { sysout("Base constructor param:" + param); } }
package com.cnblogs.common; public class Derived extends Base { 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 void main(String[] args) { Derived derived = new Derived(); derived = new Derived("参数"); derived = new Derived("参数1", "参数2"); } }
注:eclipse会报错。Implicit super constructor Base() is undefined ……说明子类中的构造函数找不到显式写出的父类中的缺省构造函数,所以出错。
示例五:
解决上面问题方法
(1)去掉父类显示的非缺省 构造函数
(2)子类的构造函数调用你显式写出的父类中的缺省 构造函数
package com.cnblogs.common; public class Derived extends Base { 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 void main(String[] args) { Derived derived = new Derived(); derived = new Derived("参数"); derived = new Derived("参数1", "参数2"); } }
注:子类如果有多个构造函数的时候,父类要么没有构造函数, 让编译器自动产生,那么在执行子类构造函数之前先执行编 译器自动产生的父类的缺省构造函数;要么至少要有一个显 式的缺省构造函数可以让子类的构造函数调用。
额外备注:
1.子类的构造过程中必须调用父类的构造方法
2.子类可在自己的构造方法中使用super()来调用父类的构造方法
3.如果子类的构造方法中没有显示的调用父类的构造方法,则系统默认的调用父类的无参的构造方法。
4.如果子类的构造方法中既没有显示调用父类的构造方法,而父类中又没有无参的构造方法,则编译出错。