动态绑定

动态绑定也叫运行时绑定,通俗的讲, 在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方法。

一个大坑:

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方法。

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

 

posted on 2021-11-27 14:52  Krcoding  阅读(289)  评论(0)    收藏  举报