Java动态(后期)绑定和overloading 向上转型
【摘要】
动态绑定:意味着 目前正在调用的方法正是最适用于要操作对象的那个方法。然而它并不意味着对所有的参数都执行最佳匹配。 在Java中,一个方法的参数在编译阶段常被
静态地绑定。
一个例子:动态绑定和静态重载
class Base{ public void foo(Base x){ Syst...
动态绑定:意味着 目前正在调用的方法正是最适用于要操作对象的那个方法。然而它并不意味着对所有的参数都执行最佳匹配。
静态地绑定一个例子:动态绑定和静态重载
-
class Base{
-
public void foo(Base x){
-
System.out.println("Base.Base");
-
}
-
-
public void foo(Derived x){
-
System.out.println("Base.Derived");
-
}
-
}
-
class Derived extends Base{
-
public void foo(Base x){
-
System.out.println("Derived.Base");
-
}
-
-
public void foo(Derived x){
-
System.out.println("Derived.Derived");
-
}
-
}
-
class Main{
-
public static void whichFoo(Base arg1, Base arg2){
-
arg1.foo(arg2);
-
}
-
-
public static void main(String[] args)}{
-
Base b = new Base();
-
Derived d = new Derived();
-
-
whichFoo(b,b);
-
whichFoo(b,d);
-
whichFoo(d,b);
-
whichFoo(d,d);
-
}
-
}
分析:
编译阶段 whichFoo方法中 arg2的类型是Base
public void foo(Base x)
惟一的问题
arg1的运行时类型
总结:
精确使用的方法是编译器绑定,在编译阶段,最佳方法名依赖于参数的静态和控制引用的静态类型所适合的方法。在这一点上,设置方法的名称,这一步叫静态重载。
决定方法是哪一个类的版本,这通过由虚拟机推断出这个对象的运行时类型来完成,一旦知道运行时类型,虚拟机就唤起继承机制,寻找方法的最终版本。这叫做动态绑定。
由此理解方法的覆盖和重载。重载函数的实际调用版本由编译器绑定决定,而覆盖函数的实际调用版本由动态绑定决定。
看一个例子:有歧义的重载
-
class Point { int x, y; }
-
class ColoredPoint extends Point { int color; }
-
-
class Test {
-
static void test(ColoredPoint p, Point q) {
-
System.out.println("(ColoredPoint, Point)");
-
}
-
static void test(Point p, ColoredPoint q) {
-
System.out.println("(Point, ColoredPoint)");
-
}
-
public static void main(String[] args) {
-
ColoredPoint cp = new ColoredPoint();
-
test(cp, cp); // compile-time error
-
}
-
}
-
分析:
这个例子会在编译时提示一个错误,错误在于声明的两个test方法在编译器看起来都是可行的,彼此之间都不具备进一步说服编译器调用自己的理由,所以编译器就为难的抛出一个存在调用歧义的错误。
如果我们增加一个test的重载定义如下:
-
static void test(ColoredPoint p, ColoredPoint q) {
-
System.out.println("(ColoredPoint, ColoredPoint)");
-
}
问题:方法的参数是父类对象,传入子类对象是否可行
引出的一连串的问题:
向上转型
程序绑定的概念:
静态绑定:
java当中的方法只有final,static,private和构造方法是前期绑定
动态绑定:
动态绑定的过程:
关于绑定相关的总结:
java属于后期绑定 几 乎 特殊 特别说明 一、 二、 C++则不同,必须明确的声明某个方法具备后期绑定。向上转型
方法 final,static,private和构造方法
其具体过程细节如下:
“重载解析”
动态绑定
上面是理论,下面看几个示例(示例来自网络):
-
public class Father {
-
public void method() {
-
System.out.println("父类方法,对象类型:" + this.getClass());
-
}
-
}
-
-
public class Son extends Father {
-
public static void main(String[] args) {
-
Father sample = new Son();//向上转型
-
sample.method();
-
}
-
}
首先
但是
向上转型
-
public class Son extends Father {
-
public void method() {
-
System.out.println("子类方法,对象类型:" + this.getClass());
-
}
-
-
public static void main(String[] args) {
-
Father sample = new Son();//向上转型
-
sample.method();
-
}
-
}
重写
在处理java类中的成员变量时,并不是采用运行时绑定,而是一般意义上的静态绑定。 对象的方法可以找到子类,而对象的属性还是父类的属性
-
public class Father {
-
-
protected String name="父亲属性";
-
-
public void method() {
-
System.out.println("父类方法,对象类型:" + this.getClass());
-
}
-
}
-
-
public class Son extends Father {
-
protected String name="儿子属性";
-
-
public void method() {
-
System.out.println("子类方法,对象类型:" + this.getClass());
-
}
-
-
public static void main(String[] args) {
-
Father sample = new Son();//向上转型
-
System.out.println("调用的成员:"+sample.name);
-
}
-
}
运行时(动态)绑定针对的范畴只是对象的方法
-
public class Father {
-
protected String name = "父亲属性";
-
public String getName() {
-
return name;
-
}
-
public void method() {
-
System.out.println("父类方法,对象类型:" + this.getClass());
-
}
-
}
-
-
public class Son extends Father {
-
protected String name="儿子属性";
-
-
public String getName() {
-
return name;
-
}
-
-
public void method() {
-
System.out.println("子类方法,对象类型:" + this.getClass());
-
}
-
-
public static void main(String[] args) {
-
Father sample = new Son();//向上转型
-
System.out.println("调用的成员:"+sample.getName());
-
}
-
}
转载自:http://www.cnblogs.com/yyyyy5101/archive/2011/08/02/2125324.html
文章来源: panda1234lee.blog.csdn.net,作者:panda1234lee,版权归原作者所有,如需转载,请联系作者。
原文链接:panda1234lee.blog.csdn.net/article/details/13685467
【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)