• 前期绑定 和 后期绑定


    thinking in java 读书笔记(感悟);
    页码:P9 (想看书上怎么讲的。自行翻看 P9 页)
    
    写于:2018年3月29日19:22:14
    
    作者:淮左白衣
    

    目录


    场景:

     public void eat(Animal animal){
            System.out.println(animal.eatSometing());
        }
    
        ....
        ....
    
        Dog dog = new Dog();
        eat(dog);
        Cat cat = new Cat();
        eat(cat);

    一眼就可以看出,这是多态;在多态的时候,我们将子类的类型向上转型为父类,进行类型的泛化,便于我们写出实用性很强的代码(新类型产生,不用修改原有代码);
    就像这里 eat 方法,接受一个 Animal类型 ;我们传进去的分别是 dogcat ;但是打印出的结果是明确的,传dog进去,输出狗吃骨头,传cat进去,输出猫吃鱼
    但是这里有个问题,不知道大家想过没有:任何类型传进去,都是父类型,但是在调用方法的时候,却是明明确确的调用了子类的方法!或者 编译器是怎么知道,具体该调用哪一个方法的呢?
    这就是本文要讲的 前期绑定后期绑定


    前期绑定

    前期绑定是 面向过程 语言的编译器的做法 ;编译器在 编译 面向过程语言的时候,在出现 函数调 用的时候,会产生一个 对具体函数名字的引用 ,这样在程序运行的时候,执行到函数调用的语句,就会发现这里一个 对XXX方法的引用,就会把执行逻辑解析到这个XXX方法的绝对地址上;

    但是这一套,到java这就不好使了,编译器在编译代码的时候,知道具体调用哪一个方法吗?编译器不是神,它不可能知道的;

    因此,我们需要另谋蹊径,伟大的计算机科学家,想到了 后期绑定


    后期绑定

    既然编译时期,编译器搞定不了方法调用的问题!那么,就在运行期,做手脚,来搞定这件事;

    java是这样来搞定方法调用的在每一个对象中存储一小段信息,通过这一小段信息,可以计算出该对象的方法地址 ;然后去调用方法

    因此上述代码的调用就可以得到理解:虽然传进去的都是 Animal引用但是引用指向的对象是Dog、Cat对象,这个对象里面保存了信息;比如Dog对象,里面就保存它的eatSomething方法在哪里 ;这样虚拟机就会调用正确的方法了 ;


    顺便讲下 编译看左边,运行看右边 的背后是什么意思吧 ;

    编译看左边,运行看右边

    这句话,好多人都知道的,但是为什么呢
    

    其实这就是后期绑定的原因 ;java的编译器,虽然在编译期间不能为方法调用做些什么,但是也不能啥也不干吧 ;(它要是不干了,虚拟机可能就不开心了,凭啥都是我在做事呀o(╥﹏╥)o) ;

    java的编译器在编译期间,会检查这个要调用的方法是否存在,调用的参数是否正确 ;返回的类型是否正确;简单说,就是做一些检查工作 ;

    这个检查工作,就是为什么编译看左边;假如父类没有这个方法,编译时过不去的,因为编译器对方法是否存在进行检查;运行看右边,是因为后期绑定,去调用具体的方法了 ;


  • 相关阅读:
    2级联动下拉列表写法
    select选中获取索引三种写法
    判断设备-安卓|苹果|微信
    限制输入字符个数的jq插件
    面试题:1.清空字符串前后的空格;2.找出出现最多的字符
    css3玩转各种效果【资源】
    利用jquery.touchSwipe.js实现的移动滑屏效果。
    【leetcode刷题笔记】Letter Combinations of a Phone Number
    【leetcode刷题笔记】Linked List Cycle
    【leetcode刷题笔记】Length of Last Word
  • 原文地址:https://www.cnblogs.com/young-youth/p/11665746.html
Copyright © 2020-2023  润新知