动态绑定

动态绑定

动态绑定也叫运行时绑定,通俗的讲, 在Java中, 调用某
个类的方法,究竟执行了哪段代码(是父类方法的代码还
是子类方法的代码) , 要看究竟这个引用指向的是父类对
象还是子类对象. 这个过程是程序运行时决定的(而不是
编译期), 因此称为 动态绑定.

发生的条件

1、父类引用引用子类对象

2、通过父类引用调用父类和子类的同名覆盖方法

例如

class X{
    public void eat(){
        System.out.print("父类吃");
    }
}
class Y extends X {
    public void eat(){
        System.out.print("子类吃");
    }
}
public class dd {

    public static void main(String[] args) {
        X x=new Y();
        x.eat();
    }
}

在这里插入图片描述
发生动态绑定时,父类引用调用父类和子类的同名覆盖方法,执行的是子类里的方法,如上例中子类Y里的eat方法。

在构造方法中调用重写的方法(一个坑)

一段有坑的代码. 我们创建两个类, B 是父类, D 是子类. D 中重写 func 方法. 并且在 B 的构造方法中调用 func

class B { 
 public B() { 
 func(); 
 } 
 public void func() { 
 System.out.println("B.func()"); 
 } 
} 
class D extends B { 
 private int num = 1; 
 @Override 
 public void func() { 
 System.out.println("D.func() " + num); 
 } 
} 
public class Test { 
 public static void main(String[] args) { 
 D d = new D();
  } 
} 
// 执行结果
D.func() 0

分析

1、构造 D 对象的同时, 会调用 B 的构造方法.
2、B 的构造方法中调用了 func 方法, 此时会触发动态绑定, 
会调用到 D 中的 func方法。
3、此时 D 对象自身还没有构造, 此时 num 处在未初始化
的状态, 值为 0.

为什么说这是一个坑?
因为在一般情况下,我们其实想调用的是类B里的func方法,
但发生了动态绑定,调用了子类D中的func方法。

结论: "用尽量简单的方式使对象进入可工作状态", 尽量不要
在构造器中调用方法(如果这个方法被子类重写, 就会触发动
态绑定, 但是此时子类对象还没构造完成), 可能会出现一些
隐藏的但是又极难发现的问题.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值