初始化基类

560 阅读2分钟

初始化基类

从外部看,新类与基类具有相同的接口,可能还有一些额外的方法和字段。但是继承并不只是复制基类的接口。当你创建派生类的对象时,它包含基类的子对象。这个子对象与你自己创建基类的对象是一样的。只是从外部看,基类的子对象被包装在派生类的对象中。

初始化基类子对象只有一种方法,那就是在派生类中调用基类构造函数进行初始化,该构造函数具有执行基类初始化所需的所有适当信息和特权。Java 自动在派生类构造函数中插入对基类构造函数的调用。

package cn.strugglenow.Test;

// reuse/Cartoon.java
// (c)2017 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
// Constructor calls during inheritance

class Art {
    Art() {
        System.out.println("Art constructor");
    }
}

class Drawing extends Art {
    Drawing() {
        System.out.println("Drawing constructor");
    }
    Drawing(int i){
        System.out.println("Drawing带参构造器");
    }
    static {
        System.out.println("静态初始化Drawing");
    }
}

 class Cartoon extends Drawing {
    public Cartoon(int i) {
        System.out.println("Cartoon constructor");
    }
    public static void main(String[] args) {
        Cartoon x = new Cartoon(1);
    }
}
/**
静态初始化Drawing
Art constructor
Drawing constructor
Cartoon constructor
**/

从结果来看,在派生类中回默认调用基类的无参构造器,如果我们删除基类的无参构造器,那么编译器会报错

There is no default constructor available in 'cn.strugglenow.Test.Drawing'

super关键字

super关键字其实就是在派生类中指向基类子对象的引用,可以用super调用基类的字段以及方法,还可以调用基类的构造器。在派生类构造方法中调用基类构造方法super(),则super()必须放到方法的第一行。

package cn.strugglenow.Test;

// reuse/Cartoon.java
// (c)2017 MindView LLC: see Copyright.txt
// We make no guarantees that this code is fit for any purpose.
// Visit http://OnJava8.com for more book information.
// Constructor calls during inheritance

class Art {
    Art() {
        System.out.println("Art constructor");
    }
}

class Drawing extends Art {
    Drawing() {
        System.out.println("Drawing的无参构造器");
    }
    Drawing(int i){
        System.out.println("Drawing带参构造器,传入的参数是"+i);
    }
    static {
        System.out.println("静态初始化Drawing");
    }
}

 class Cartoon extends Drawing {
    public Cartoon() {
        super(4);//防止默认调用基类的无参构造器
        System.out.println("Cartoon constructor");
    }
    public static void main(String[] args) {
        Cartoon x = new Cartoon();
    }
}

ps:

  • 子对象:对象能够包含其他对象,被包含的对象就叫子对象。子对象可以是成员子对象基类子对象或者是数组的成员。如果一个对象不是任何对象的子对象,那么这个对象称为完全对象
  • 基类子对象:派生类是对基类的扩展,所以派生类对象内部一定有一份基类对象的存在,这份基类对象,本质上是派生类对象的一部分,直接存放在派生类对象内部,不是独立的对象,称之为基类子对象