java中的动态绑定和静态绑定

本文通过一个具体的Java代码示例,详细解释了多态性和重载的区别,特别是如何在运行时确定调用哪个方法的过程。文章还探讨了静态绑定和动态绑定的概念及其在Java中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


public class TestOverwrite {
        public static void main(String []args){
                Father father = new Son();
                Son son = new Son();
                father.show(son); //show:Son:father
                father.display(son); //display:Father:father
        }
}
class Father{
        void show(Father father){
                System.out.println("show:Father:father");
        }
        static void display(Father father){
                System.out.println("display:Father:father");
        }
}
class Son extends Father{
        void show(Father father){
                System.out.println("show:Son:father");
        }
        void show(Son father){
                System.out.println("show:Son:son");
        }
        static void display(Father father){
                System.out.println("display:Son:father");
        }
}

答案很好给出,自己在eclipse里跑一下也能知道个一二,网上有人讨论过类似问题 深入理解java多态性 ,这篇文章将多态性和重载混在一起,涉及了很多种情况,作者也给出了自己的分析“实际上这里涉及方法调用的优先问题 ,优先级由高到低依次为:this.show(O)、super.show(O)、this.show((super)O)、super.show((super)O)”,这个顺序没错,但我这里想探究下为什么是这个顺序。

Java和很多面向对象语言一样有静态绑定static-binding和动态绑定dynamic-binding两种方式,静态绑定发生于程序的编译期,动态绑定发生于程序的运行期,最直观的两个例子:重载,重写。重载发生于编译期,是静态绑定的一种,静态绑定根据函数签名进行绑定,决定最终运行哪个函数;动态绑定在运行期根据多态的机制重新决定运行哪个函数。

回到上面的程序,Father father = new Son(); 这句代码初始化了一个Father类型的引用,它指向了一个Son类型的对象,但因为向上转型的原因,在变量father看来它指向的堆空间其实是一个Father,内存图如下:
内存图,图中a为father懒得改了
内存图,图中a为father懒得改了

那么在函数编译时,father.show(b)首先查询father所指对象的函数列表,发现只有 void show(Father a); 一个函数,并且形参类型符合转型需求,与其绑定,当运行时,因为多态机制,发现void show(Father a); 函数在子类中被重写了,覆盖了父类的方法,于是动态与子类重写后的方法绑定,便得到了这样的运行结果。当然子类中另一个重载的show方法是进行迷惑的,编译时其根本不在father能调用的函数表里,一早被淘汰,后面也就没它什么事儿。

再来看看display函数,父类和子类中有签名相同的display函数,与show不同的是有static关键字,static在没有实例化时变产生,所以看似是重写,其实根本不是,也就没多态的事儿,所以编译时根据函数签名静态绑定到了父类的display,后面没有动态绑定的过程,故输出结果是父类的display的结果。

参考资料:
1. Dynamic Binding and Static Binding
2. 常见Java面试题 – 第三部分:重载(overloading)与重写(overriding)

转载自: http://www.douban.com/note/272520236/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值