多态/构造器的调用顺序/构造器内部的多态

Java实现多态的机制是后期绑定。
但Java也有些地方可以用前期绑定,比如:final,static,private(隐式final)和构造方法(隐式static)是前期绑定。
另外,Java只有普通方法的调用可以是多态的,如果直接访问某个域,这个访问将在编译期进行解析。
举例

//子类
public class Son extends Battle {
    public int a = 2;
    public int getA(){
        return a;
    }
}
//父类
public class Battle {
	public int a = 1;
	public int getA(){
		return a;
	}
	public static void main(String[] args) throws Exception {
		Battle b = new Son();
		System.out.println(b.a);
		System.out.println(b.getA());
    }
}

输出
在这里插入图片描述


构造器调用顺序
先看如下代码

class Meal {
    Meal() { System.out.println("Meal()"); }
}
class Bread {
    Bread() { System.out.println("Bread()"); }
}
class Cheese {
    Cheese() { System.out.println("Cheese()"); }
}
class Lettuce {
    Lettuce() { System.out.println("Lettuce()"); }
}
class Lunch extends Meal {
    Lunch() { System.out.println("Lunch()"); }
}
class PortableLunch extends Lunch {
    PortableLunch() { System.out.println("PortableLunch()"); }
}
public class Test extends PortableLunch {
    private Bread b = new Bread();
    private Cheese c = new Cheese();
    private Lettuce l = new Lettuce();
    public Test() { System.out.println("Test()"); }
    public static void main(String[] args) {
        new Test();
    }
}

输出
在这里插入图片描述
执行步骤是:
1、调用父类构造器。这个步骤会不断递归下去,直到构造这种层次结构的根,然后是下一层的子类,直到最底层的子类。
1、按声明顺序调用成员的初始化方法。
3、调用子类构造器的主体。
同时调用层次中某一类的构造方法时,会先初始化成员变量。
按如下顺序初始化类中的东西:

1、静态属性初始化
2、静态方法块初始化
3、普通属性初始化
4、普通方法块初始化
5、构造函数初始化

构造器内部的多态
先看代码

class Glyph{
    void draw(){
        System.out.println("Glyph draw()");
    }
    Glyph(){
        System.out.println("Glyph() before draw()");
        draw();
        System.out.println("Glyph() after fraw()");
    }
}
class RoundGlyph extends Glyph{
    private int radius = 1;
    RoundGlyph(int r){
        radius = r;
        System.out.println("RoundGlyph.RoundGlyph(), radius = " + radius);
    }
    void draw(){
        System.out.println("RoundGlyph.draw(), radius = " + radius);
    }
}
public class Test {
    public static void main(String[] args) {
        new RoundGlyph(5);
    }
}

输出
在这里插入图片描述
分析一下代码运行过程:

  1. 在其他任何事物发生之前,将分配给对象的存储空间初始化为二进制的零。
  2. 如上文一般,虚拟机在查看类的类型信息的时候,如果发现有父类,则继续去加载父类的类文件,如果没有父类了,则开始初始化类,再然后执行构造器。
  3. 这时在执行Glyph的构造器时发现它调用了子类重写的draw方法,在这是一个多态。由于子类还没有初始化,这时radius是刚开始分配存储空间时初始化的0,因此打印出 RoundGlyph.draw(), radius = 0。
  4. 按照声明的顺序调用成员的初始化方法。
  5. 调用子类的构造器。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值