Java子父类中的构造函数实例化过程

其实我们发现子类继承父类操作很简单,如果要是去深入的研究下会发现,实例化过程并非是我们看到的那样,我们就以代码举例来说明;


问大家,以下代码执行会输出什么呢?

package com.oop;

/**
 * 定义动物对象
 * @author Liudeli
 *
 */
class Animal {

    public Animal() {
        System.out.println("Animal()--构造函数");
    }

}

/**
 * 定义狗对象
 * @author Liudeli
 *
 */
class Dog extends Animal{

}

/**
 * 子父类中的构造函数实例化过程
 * @author Liudeli
 *
 */
public class Demo1 {

    public static void main(String[] args) {

        Dog d = new Dog();

    }

}

没有去深究这个问题,大部分会回答,不输出任何,因为Dog类没有任何构造方法,如果这样想的其实就错了,它一定会输出父类无参构造方法的内容:

这里写图片描述

这是为什么呢?
答:其实只要我们随便创建一个类,就会有隐式的代码重点内容执行
会在子类的构造方法中执行 super(); 调用

/**
 * 定义狗对象
 * @author Liudeli
 *
 */
class Dog extends Animal{

    // 其实只要我们随便创建一个类,就会有隐式的代码执行,只是我们看不到而已
    Dog() {
        super();
        return;
    }

}


子类有一个有参构造方法,new 子类(true),调用子类的有参构造方法,父类的无参构造方法一定会执行,因为在子类的任何构造方法中,都会默认调用 super();

package com.oop;

/**
 * 定义动物对象
 * @author Liudeli
 *
 */
class Animal2 {

    public Animal2() {
        System.out.println("Animal()--构造函数");
    }

    public Animal2(boolean is) {
        System.out.println("Animal2(boolean is)--构造函数 is:" + is);
    }

}

/**
 * 定义狗对象
 * @author Liudeli
 *
 */
class Dog2 extends Animal{


    public Dog2() {

    }

    public Dog2(boolean is) {
        System.out.println("Dog2(boolean is)--构造函数 is:" + is);
    }

}

/**
 * 子父类中的构造函数实例化过程
 * @author Liudeli
 *
 */
public class Demo2 {

    public static void main(String[] args) {

        // 我调用的是,子类的有参构造方法,父类的无参构造方法会执行
        // 因为在子类的任何构造方法中,都会执行super();
        Dog2 dog = new Dog2(true);

    }

}

运行结果:
这里写图片描述



我们看不到的细节:

package com.oop;

/**
 * 定义动物对象
 * @author Liudeli
 *
 */
class Animal3 {

    public Animal3() {
        System.out.println("Animal()--构造函数");
    }

    public Animal3(boolean is) {
        System.out.println("Animal(boolean is)--构造函数 is:" + is);
    }

}

/**
 * 定义狗对象
 * @author Liudeli
 *
 */
class Dog3 extends Animal{


    public Dog3() {
        // super(); 默认就有,只是我们看不到而已,super()它在子类任何构造函数中的第一行
        super(false);  // 这样写报错,为什么会报错因为在子类的任何构造函数中都会执行 super()
                       // 你如果写了 super(参数); 就是不认它调用父类的super(), 所以它会报错
    }

    public Dog3(boolean is) {
        // super(); 默认就有,只是我们看不到而已,super()它在子类任何构造函数中的第一行
        super(false);  // 这样写报错,为什么会报错因为在子类的任何构造函数中都会执行 super()
                       // 你如果写了 super(参数); 就是不认它调用父类的super(), 所以它会报错
        System.out.println("Dog(boolean is)--构造函数 is:" + is);
    }

}

/**
 * 子父类中的构造函数实例化过程
 * @author Liudeli
 *
 */
public class Demo3 {

    /*
     *  Demo3 的实例化必须执行以下代码,只是隐式的看不到而已
     */
    // 主要 修饰符 public 是由于类开始定义的是public,所以它才是public,修饰符根据类的定义变化而变化
    public Demo3() {
        super();
        return;
    }

    public static void main(String[] args) {

        Dog3 dog = new Dog3(true);

    }

}

在这里有一个思考点,创建一个类不继承任何类,默认无参构造函数必须执行 super(); ,那super调用了那个父类的无参构造函数?

答:最终超类 Object。

所以我们这样写,没有任何问题,extends Object

package com.oop;

// 系统默认或直接间接的让Object成为了父类,extends Object,只是我们看不到而已
public class Demo4 extends Object {  

    /*
     *  Demo3 的实例化必须执行以下代码,只是隐式的看不到而已
     */
    // 主要 修饰符 public 是由于类开始定义的是public,所以它才是public,修饰符根据类的定义变化而变化
    public Demo4() {
        super();
        return;
    }

    public static void main(String[] args) {
        System.out.println("Demo4()...");
    }

}

运行结果:
这里写图片描述


父类写了一个有参构造方法,子类继承父类,子类必须要写一个和父类一样参数的构造方法,因为父类写了一个有参构造方法,父类的无参构造方法就没有了,子类的无参构造方法就调用不到父类的无参构造方法了,需要让子类的有参构造方法去super()调用;

public  class Observer {

    private String name;
    private Secretary secretary;

    public Observer(String name, Secretary secretary) {
        this.name = name;
        this.secretary = secretary;
    }

}
public class StockObserver extends Observer{

    // 子类必须要写一个和父类同参的构造方法
    public StockObserver(String name, Secretary secretary) {
        super(name, secretary);
        // TODO Auto-generated constructor stub
    }
}

谢谢大家的观看,更多精彩技术博客,会不断的更新,请大家访问,
刘德利CSDN博客, http://blog.csdn.net/u011967006

原文地址:https://www.cnblogs.com/android-deli/p/10322204.html