Java的动态绑定

来源:互联网 发布:不想谈恋爱知乎 编辑:程序博客网 时间:2024/04/29 23:28

http://blog.sina.com.cn/s/blog_59c9412d0100g7is.html 

运行时绑定也叫动态绑定,它是一种调用对象方法的机制。Java调用对象方法时,一般采用运行时绑定机制。
1.Java的方法调用过程
编译器查看对象的声明类型和方法名(对象变量的声明类型)。通过声明类型找到方法列表。
编译器查看调用方法时提供的参数类型。
如果方法是private、static、final或者构造器,编译器就可以确定调用那个方法。这是静态绑定。
如果不是上述情况,就要使用运行时(动态)绑定。在程序运行时,采用动态绑定意味着:虚拟机将调用对象实际类型所限定的方法。
2.运行时(动态)绑定的过程
虚拟机提取对象的实际类型的方法表;
虚拟机搜索方法签名;
调用方法。
注意,这里说的是对象的实际类型。即在多态的情况下,虚拟机可以找到所运行对象的真正类型。
3.在向上转型情况下的动态绑定示例

Code:
  1.  public class Father {    
  2.      public void method() {    
  3.         System.out.println(" 父类方法,对象类型:" + this.getClass());    
  4.      }    
  5.  }    
  6.   
  7.  public class Son extends Father {    
  8.     public static void main(String[] args) {    
  9.        Father sample = new Son();// 向上转型    
  10.        sample.method();    
  11.     }    
  12.  }      

结果1:

父类方法,对象类型:class samples.Son

这个结果没有疑问,声明的是父类的引用(句柄),但准确的调用了子类的对象,调用method,在子类中没有该方法,所以去父类中寻找到并调用之。

现在修改子类,重写(override)method方法。

Java代码
Code:
  1. public class Son extends Father {    
  2.     public void method() {    
  3.        System.out.println(" 子类方法,对象类型:" + this.getClass());    
  4.    }    
  5.        
  6.  public static void main(String[] args) {    
  7.        Father sample = new Son();// 向上转型    
  8.       sample.method();    
  9.     }    
  10. }    
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();     } } 

结果2:

子类方法,对象类型:class samples.Son

这个结果也是意料之中的。调用method时,在子类中寻找到了该方法,所以直接调用之。

4.静态绑定成员变量

在处理Java类中的成员变量时,并不是采用运行时绑定,而是一般意义上的静态绑定。所以在向上转型的情况下,对象的方法可以“找到”子类,而对象的属性 还是父类的属性。

现在再进一步变化,在父类和子类中同时定义和赋值同名的成员变量name,并试图输出该变量的值。

Java代码
Code:
  1. public class Father {    
  2.      protected String name=" 父亲属性";    
  3.         
  4.      public void method() {    
  5.         System.out.println(" 父类方法,对象类型:" + this.getClass());    
  6.      }    
  7.  }    
  8.       
  9.  public class Son extends Father {    
  10.      protected String name=" 儿子属性";    
  11.         
  12.    public void method() {    
  13.         System.out.println(" 子类方法,对象类型:" + this.getClass());    
  14.      }    
  15.         
  16.      public static void main(String[] args) {    
  17.         Father sample = new Son();// 向上转型    
  18.         System.out.println(" 调用的成员:"+sample.name);    
  19.      }    
  20.  }    
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);     } } 

结果3:

调用的成员:父亲属性

这个结果表明,子类的对象(由父类的引用handle)调用到的是父类的成员变量。所以必须明确,运行时(动态)绑定针对的范畴只是对象的方法。

现在试图调用子类的成员变量name,该怎么做?最简单的办法是将该成员变量封装成方法getter形式。

Java代码
Code:
  1. public class Father {    
  2.      protected String name = " 父亲属性";    
  3.       
  4.      public String getName() {    
  5.         return name;    
  6.     }    
  7.       
  8.      public void method() {    
  9.         System.out.println(" 父类方法,对象类型:" + this.getClass());    
  10.      }    
  11.  }    
  12.       
  13.  public class Son extends Father {    
  14.      protected String name=" 儿子属性";    
  15.         
  16.      public String getName() {    
  17.        return name;    
  18.      }    
  19.         
  20.      public void method() {    
  21.         System.out.println(" 子类方法,对象类型:" + this.getClass());    
  22.      }    
  23.         
  24.      public static void main(String[] args) {    
  25.         Father sample = new Son();// 向上转型    
  26.         System.out.println(" 调用的成员:"+sample.getName());    
  27.      }    
  28.  }    
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());     } } 

结果4:

调用的成员:儿子属性

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 苹果手机打开软件打不开怎么办 苹果电脑下载的软件打不开怎么办 苹果手机下载的软件都打不开怎么办 苹7果屏幕黑屏怎么办 苹果6s手机打不开怎么办 苹果ipad密码输入打不开怎么办 苹果平板黑屏了打不开怎么办 苹果6sp电影商城打不开怎么办 苹果6应用商城打不开怎么办 游戏下载好了安装不上怎么办 苹果5s应用商店不见了怎么办 id被停用手机白板打不开怎么办 苹果6s下载不了软件怎么办 苹果下载的软件打不开怎么办 苹果6s下不了app怎么办 苹果手机因为闪退打不开了怎么办 天猫方糖坏了怎么办 天猫魔盒的遥控器坏了怎么办 天猫盒子没声音怎么办 天猫魔盒播放声音很低怎么办 天猫魔盒3a卡顿怎么办 天猫网络机顶盒打不开了怎么办 天猫机顶盒遥控器丢了怎么办 天猫机顶盒没有遥控器怎么办 天猫机顶盒很卡怎么办 天猫机顶盒没遥控器怎么办 天猫机顶盒看不了怎么办 天猫机顶盒变黑白怎么办 天猫精灵丢了怎么办 咪咕盒子没信号怎么办 猫los灯亮了怎么办 网络猫los闪红灯怎么办 台式电脑二级网页打不开.怎么办 光纤猫los红闪怎么办 系统管理员账户密码被更改怎么办 花呗不能使用了怎么办 开通余额宝提示身份验证失败怎么办 蚂蚁花呗刷脸认证老失败怎么办 火狐浏览器登录系统后打不开怎么办 花呗自动扣费怎么办 彪马运动裤买大了怎么办