java中的动态绑定和静态绑定
2014-11-14 09:24
274 查看
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,内存图如下:
那么在函数编译时,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/
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懒得改了 |
再来看看display函数,父类和子类中有签名相同的display函数,与show不同的是有static关键字,static在没有实例化时变产生,所以看似是重写,其实根本不是,也就没多态的事儿,所以编译时根据函数签名静态绑定到了父类的display,后面没有动态绑定的过程,故输出结果是父类的display的结果。
参考资料:
1.Dynamic
Binding and Static Binding
2.常见Java面试题
– 第三部分:重载(overloading)与重写(overriding)
转载自: http://www.douban.com/note/272520236/
相关文章推荐
- java的动态绑定与静态绑定
- java的动态绑定与静态绑定
- 学习笔记之 java的动态绑定与静态绑定
- Java 基础(8)—— 向上转型、向下转型、动态绑定、静态绑定
- java动态绑定和静态绑定(分步验证)
- c++动态绑定、静态绑定与java中动态绑定与静态绑定的比较
- Java的动态绑定和静态绑定
- java的动态绑定与静态绑定
- java的动态绑定与静态绑定
- Java中的动态绑定和静态绑定
- Java方法的静态绑定与动态绑定讲解(向上转型的运行机制详解)
- Java中静态绑定与动态绑定详解
- Java静态绑定与动态绑定 隐藏 多态
- java的动态绑定与静态绑定
- Java学习笔记之深入理解动态绑定和静态绑定
- 从Java静态绑定和动态绑定中得到优化启示
- Java方法的动态绑定与静态绑定
- 【Java学习】Java方法的静态绑定与动态绑定讲解
- java动态绑定静态绑定
- Java静态绑定与动态绑定