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.如果子类的构造方法中既没有显示调用父类的构造方法,而父类中又没有无参的构造方法,则编译出错。

posted @ 2014-09-18 15:40  学无先后 达者为先  阅读(654)  评论(0编辑  收藏  举报