A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 全海波 中级黑马   /  2012-9-1 17:04  /  2403 人查看  /  3 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 全海波 于 2012-9-2 08:06 编辑

动态绑定是多态吗?如不是,请详细阐述!那静态绑定又该如何理解?最好举一个例子说明!

3 个回复

倒序浏览
静态绑定:静态绑定又称前期绑定,即在程序执行前方法已经被绑定,此时由编译器或其它连接程序实现。针对java简单的可以理解为程序编译期的绑定;这里特别说明一点,java当中的方法只有final,static,private和构造方法是前期绑定。
动态绑定:动态绑定又称后期绑定,在运行时根据具体对象的类型进行绑定。在java中,几乎所有的方法都是后期绑定的,在运行时动态绑定方法属于子类还是基类。但是也有特殊,针对static方法和final方法由于不能被继承,因此在编译时就可以确定他们的值,他们是属于前期绑定的。特别说明的一点是,private声明的方法和成员变量不能被子类继承,所有的private方法都被隐式的指定为final的(由此我们也可以知道:将方法声明为final类型的一是为了防止方法被覆盖,二是为了有效的关闭java中的动态绑定)。java中的后期绑定是有JVM来实现的,我们不用去显式的声明它。
动态绑定的过程:虚拟机提取对象的实际类型的方法表,虚拟机搜索方法签名,调用对应方法。
实际上就是视频说的那样编译和运行都参考左边的就是静态绑定,编译时参考左边的,运行时参考右边的肯定是动态绑定。动态绑定要么继承要么实现。

评分

参与人数 1技术分 +1 收起 理由
张立江 + 1

查看全部评分

回复 使用道具 举报
本帖最后由 马小龙 于 2012-9-1 22:37 编辑

动态绑定是指在执行期间(非编译期)判断所引用对象的实际类型,根据其实际的类型调用其相应的方法.(静态绑定发生于运行期间)
  1. package com.itheima;

  2. public class Test3 {
  3.         
  4.         public  static void main(String[] args){
  5.                 //在运行时才去判断是执行子类的say方法,
  6.                 base test = new base();               
  7.                 test.say();
  8.         }

  9.         public void say(){
  10.                 System.out.println("I'm father");
  11.         }        
  12. }

  13. class base extends Test3{
  14.         
  15.         public void say(){
  16.                 System.out.println("I'm son");
  17.         }
  18. }
复制代码
静态绑定是指在程序编译过程中,把函数(方法或者过程)调用与响应调用所需的代码结合的过程称之为静态绑定。(静态绑定发生于编译期)
我理解的多态就是一个对象变量(object variable,与基本数据类型的变量相对应)可以指向(refer to)多个类型的对象,这就是多态

评分

参与人数 1技术分 +1 收起 理由
张立江 + 1

查看全部评分

回复 使用道具 举报
Java中绑定有两种形式静态绑定static-binding(早绑定early-binding)和动态绑定dynamic-binding(晚绑定late-binding,或运行时绑定runtime-binding)
静态绑定是在编译时绑定,而动态绑定是在运行时根据对象的实际情况来选择绑定父类或者是某个子类的方法
在执行效率上,静态绑定要优于动态绑定,但丧失了灵活性。
Java中变量是动态绑定的,实例方法是动态绑定的。在进行“向上转型”的时候子类会覆盖父类的实例方法而不会覆盖父类的变量。
举例1:
  1. public class Father {
  2. public void method() {
  3. System.out.println("父类方法,对象类型:" + this.getClass());
  4. }
  5. }

  6. public class Son extends Father {
  7. public static void main(String[] args) {
  8. Father sample = new Son();//向上转型
  9. sample.method();
  10. }
  11. }
复制代码
结果1:
父类方法,对象类型:class samples.Son
这个结果没有疑问,声明的是父类的引用(句柄),但准确的调用了子类的对象,调用method,在子类中没有该方法,所以去父类中寻找到并调用之。
举例2:
  1. public class Father {
  2. public void method() {
  3. System.out.println("父类方法,对象类型:" + this.getClass());
  4. }
  5. }
  6. public class Son extends Father {
  7. public void method() {
  8. System.out.println("子类方法,对象类型:" + this.getClass());
  9. }

  10. public static void main(String[] args) {
  11. Father sample = new Son();//向上转型
  12. sample.method();
  13. }
  14. }
复制代码
结果2:
子类方法,对象类型:class samples.Son
这个结果也是意料之中的。调用method时,在子类中寻找到了该方法,所以直接调用之。
以上两个都是动态绑定的结果。
举例3:
  1. public class Father {
  2. protected String name="父亲属性";

  3. public void method() {
  4. System.out.println("父类方法,对象类型:" + this.getClass());
  5. }
  6. }

  7. public class Son extends Father {
  8. protected String name="儿子属性";

  9. public void method() {
  10. System.out.println("子类方法,对象类型:" + this.getClass());
  11. }

  12. public static void main(String[] args) {
  13. Father sample = new Son();//向上转型
  14. System.out.println("调用的成员:"+sample.name);
  15. }
  16. }
复制代码
结果3:
调用的成员:父亲属性
这个结果表明,子类的对象(由父类的引用handle)调用到的是父类的成员变量。所以必须明确,运行时(动态)绑定针对的范畴只是对象的方法。
对于成员变量,就是静态绑定,不管子类是否复写了父类的成员变量,当访问的时候都是访问的父类的成员变量。
如果想要访问子类的成员变量,所需要的方法就是复写父类的getter和setter方法。

评分

参与人数 1技术分 +1 收起 理由
张立江 + 1 赞一个!

查看全部评分

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马