构造器和多态

一.基本介绍

1.1构造器默认为static方法——static方法默认为final方法;
1.2基类构造器调用顺序

检查对象是否被争取构造是构造器的一项任务。

1.1导出类会按照继承层次逐渐向上调用基类构造器,1.2然后按照声明顺序调用成员初始化方法,1.3最后调用导出类构造器主体;

如果没有明确调用(super关键字)哪个基类构造器,则默认调用(无参),若基类没有默认构造器的话编译报错。示例如下:

//编译失败
class Grandfather{
    int tag=0;

    public Grandfather(int tag) {
        this.tag = tag;
    }
}

class Father extends Grandfather{
    public Father() {
        super(1);//去掉这一句,则默认调用基类无参构造函数,编译失败
        System.out.println("father");
    }
}
//1.1导出类会按照继承层次逐渐向上调用基类构造器,1.2然后按照声明顺序调用成员初始化方法,1.3最后调用导出类构造器主题;

class Grandfather{
    int tag=0;

    public Grandfather(int tag) {
        System.out.println("ground father");
        this.tag = tag;
    }
}

class Father extends Grandfather{
    public Father() {
        super(1);
        System.out.println("father");
    }
}

class Son extends Father{
    public Son() {
        System.out.println("son");
    }
}

public class Demo01 {
    public static void main(String[] args) {
        new Son();
    }
}

output:
    ground father
    father
    son
1.3构造器内部的多态方法的行为

多态方法即导出类重写父类的方法:

  1. 如果这个方法在父类构造器中使用,则调用的是子类重写后的方法;
  2. 假若这个方法调用了子类某个变量,则这个变量因为还未在导出类中用其初始化方法,此时分配给变量的存储空间初始化成二进制的0;

示例如下:

class father{
    public father() {
        func();
    }

    void func(){ }
}

class son extends father{
    int tag=1;

    public son(int tag) {
        // System.out.println("tag = "+tag);这里默认调用了父类的构造方法;
        this.tag = tag;
        System.out.println("tag = "+tag);
    }
    
    @Override
    void func() {
        System.out.println("tag = "+tag);
    }
}
public class Demo02 {
    public static void main(String[] args) {
        new son(1);
    }
}

output:
    tag = 0//分配给对象的存储空间初始化为二进制的零;
    tag = 1

由上述可知初始化的实际顺序为:

  1. 将分配给对象的存储空间初始化为二进制的零;
  2. 调用基类构造器,构造函数中调用方法为覆盖后的方法;
  3. 导出类中按照声明顺序调用成员的初始化方法;
  4. 调用导出类构造器主体;

[注]

  1. 导出类应该避免调用其他方法,或者调用基类中final方法——不能被改变的方法;
  2. 导出类能够调用基类构造函数,但没有继承;

posted on 2018-04-21 13:43  coderDu  阅读(164)  评论(0编辑  收藏  举报