黑马程序员技术交流社区
标题: 动态绑定与静态绑定疑问?[已解决] [打印本页]
作者: 全海波 时间: 2012-9-1 17:04
标题: 动态绑定与静态绑定疑问?[已解决]
本帖最后由 全海波 于 2012-9-2 08:06 编辑
动态绑定是多态吗?如不是,请详细阐述!那静态绑定又该如何理解?最好举一个例子说明!
作者: 庄星睿 时间: 2012-9-1 20:54
静态绑定:静态绑定又称前期绑定,即在程序执行前方法已经被绑定,此时由编译器或其它连接程序实现。针对java简单的可以理解为程序编译期的绑定;这里特别说明一点,java当中的方法只有final,static,private和构造方法是前期绑定。
动态绑定:动态绑定又称后期绑定,在运行时根据具体对象的类型进行绑定。在java中,几乎所有的方法都是后期绑定的,在运行时动态绑定方法属于子类还是基类。但是也有特殊,针对static方法和final方法由于不能被继承,因此在编译时就可以确定他们的值,他们是属于前期绑定的。特别说明的一点是,private声明的方法和成员变量不能被子类继承,所有的private方法都被隐式的指定为final的(由此我们也可以知道:将方法声明为final类型的一是为了防止方法被覆盖,二是为了有效的关闭java中的动态绑定)。java中的后期绑定是有JVM来实现的,我们不用去显式的声明它。
动态绑定的过程:虚拟机提取对象的实际类型的方法表,虚拟机搜索方法签名,调用对应方法。
实际上就是视频说的那样编译和运行都参考左边的就是静态绑定,编译时参考左边的,运行时参考右边的肯定是动态绑定。动态绑定要么继承要么实现。
作者: 小黑马 时间: 2012-9-1 22:31
本帖最后由 马小龙 于 2012-9-1 22:37 编辑
动态绑定是指在执行期间(非编译期)判断所引用对象的实际类型,根据其实际的类型调用其相应的方法.(静态绑定发生于运行期间)- package com.itheima;
- public class Test3 {
-
- public static void main(String[] args){
- //在运行时才去判断是执行子类的say方法,
- base test = new base();
- test.say();
- }
- public void say(){
- System.out.println("I'm father");
- }
- }
- class base extends Test3{
-
- public void say(){
- System.out.println("I'm son");
- }
- }
复制代码 静态绑定是指在程序编译过程中,把函数(方法或者过程)调用与响应调用所需的代码结合的过程称之为静态绑定。(静态绑定发生于编译期)
我理解的多态就是一个对象变量(object variable,与基本数据类型的变量相对应)可以指向(refer to)多个类型的对象,这就是多态
作者: 郑义 时间: 2012-9-2 07:36
Java中绑定有两种形式静态绑定static-binding(早绑定early-binding)和动态绑定dynamic-binding(晚绑定late-binding,或运行时绑定runtime-binding)
静态绑定是在编译时绑定,而动态绑定是在运行时根据对象的实际情况来选择绑定父类或者是某个子类的方法。
在执行效率上,静态绑定要优于动态绑定,但丧失了灵活性。
Java中变量是动态绑定的,实例方法是动态绑定的。在进行“向上转型”的时候子类会覆盖父类的实例方法而不会覆盖父类的变量。
举例1:- 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();
- }
- }
复制代码 结果1:
父类方法,对象类型:class samples.Son
这个结果没有疑问,声明的是父类的引用(句柄),但准确的调用了子类的对象,调用method,在子类中没有该方法,所以去父类中寻找到并调用之。
举例2:- public class Father {
- public void method() {
- System.out.println("父类方法,对象类型:" + this.getClass());
- }
- }
- 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时,在子类中寻找到了该方法,所以直接调用之。
以上两个都是动态绑定的结果。
举例3:- 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)调用到的是父类的成员变量。所以必须明确,运行时(动态)绑定针对的范畴只是对象的方法。
对于成员变量,就是静态绑定,不管子类是否复写了父类的成员变量,当访问的时候都是访问的父类的成员变量。
如果想要访问子类的成员变量,所需要的方法就是复写父类的getter和setter方法。
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) |
黑马程序员IT技术论坛 X3.2 |