轻松理解java前期绑定(静态绑定)与后期绑定(动态绑定) 的区别。

理论概念:(乍一看有些晦涩,建议先看代码再看概念~~)

 以下是《java编程思想》原句摘抄:

程序绑定的概念:
绑定指的是一个方法的调用方法所在的类(方法主体)关联起来。对java来说,绑定分为前期绑定(静态绑定)与后期绑定(动态绑定)。

静态绑定
程序执行前方法已经被绑定(也就是说在编译过程中就已经知道这个方法到底是哪个类中的方法),此时由编译器或其它连接程序实现。
针对java简单的可以理解为程序编译期的绑定;这里特别说明一点,java当中的方法只有final,static,private和构造方法是前期绑定

动态绑定
后期绑定:在运行时根据具体对象的类型进行绑定。
若一种语言实现了后期绑定,同时必须提供一些机制,可在运行期间判断对象的类型,并分别调用适当的方法。也就是说,编译器此时依然不知道对象的类型,但方法调用机制能自己去调查,找到正确的方法主体。不同的语言对后期绑定的实现方法是有所区别的。但我们至少可以这样认为:它们都要在对象中安插某些特殊类型的信息。

代码实例:

动态绑定  :测试类,主要看它的invoke(Father f)方法,该方法接收一个父类的引用,并在其中调用父类f的方法。

Father Son  :父类与子类,父类有static、final、private、普通(other)、四种不同类型的方法,而子类Son都对这些方法进行了重写,(除了父类中的final方法,final方法不可以被子类重写,否则就报错)。

/**
 * @author XIAOHANG
 * @date 2019/8/23
 * @description 前期绑定(静态绑定)与后期绑定(动态绑定) 的区别。
 */
public class 动态绑定 {
    public static void main(String args[]){
        动态绑定 d = new 动态绑定();
        d.invoke(new Son());
    }

    public void invoke(Father f) {
        f.play_static();
        //f.play_private(); 无法访问父类的private方法,编译器报错。
        f.play_final();
        f.play_other();
    }
}

class Father{
    public String name = "Father";

    static void play_static() {
        System.out.println("Father play");
    }

    final void play_final() {
        System.out.println("Father play");
    }

    private void play_private() {
        System.out.println("Father play");
    }

    void play_other() {
        System.out.println("Father play");
    }
}

class Son extends Father{
    public String name = "Son";

    static void play_static() {
        System.out.println("Son play");
    }

    /*final void play_final() {  // 无法重写父类的final方法, 否则编译器标错。
        System.out.println("Son play");
    }*/

    private void play_private() {
        System.out.println("Son play");
    }

    void play_other() {
        System.out.println("Son play");
    }
}

输出:

Father play
Father play
Son play

 

 解释:

 这里要注意的是我们的public void invoke(Father f)这个方法,它接收的是一个Father类型的参数,但是呢,我们在调用这个方法的时候,却这样

d.invoke(new Son());

我们向它传入了一个Son对象!这样可以吗?这样是可以的,这就是java向上转型带来的好处:子类可以当做父类用。编译器在调用invoke方法时实际上是这么处理传入参数的:Father f = new Son();父类引用指向子类对象!那么在invoke方法中我们调用 f 的方法的时候到底是调用Son的,还是调用Father的呢?

这就是动态绑定的神奇之处,如果我们调用的是 f 的static、final、private、这三种方法(红字与文章开头的红字对应),就是使用了静态绑定,虽然传入的是Son对象,但调用的仍是父类的方法,所以输出两个Father play,但如果我们调用的不是这三种方法(比如other方法),那我们使用的就是动态绑定,这时候我们调用的就是子类重写父类的方法play_other(),所以输出的是Son play。

这是最直观的动态绑定与静态绑定的区别的体现。

欢迎大家提问拍砖!

  • 10
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

请保持优秀。

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值