美文网首页
多态:动态绑定

多态:动态绑定

作者: susu2016 | 来源:发表于2017-10-09 16:56 被阅读15次

    动态绑定

    程序绑定的概念:
    绑定指的是一个方法的调用与方法所在的类(方法主体)关联起来。对java来说,绑定分为静态绑定和动态绑定;或者叫做前期绑定和后期绑定.

    静态绑定:
    在程序执行前方法已经被绑定(也就是说在编译过程中就已经知道这个方法到底是哪个类中的方法),此时由编译器或其它连接程序实现。例如:C。
    针对java简单的可以理解为程序编译期的绑定;这里特别说明一点,java当中的方法只有final,static,private和构造方法是前期绑定

    动态绑定:
    后期绑定:在运行时根据具体对象的类型进行绑定。
    若一种语言实现了后期绑定,同时必须提供一些机制,可在运行期间判断对象的类型,并分别调用适当的方法。也就是说,编译器此时依然不知道对象的类型,但方法调用机制能自己去调查,找到正确的方法主体。不同的语言对后期绑定的实现方法是有所区别的。但我们至少可以这样认为:它们都要在对象中安插某些特殊类型的信息。
    动态绑定的过程:

    1. 虚拟机提取对象的实际类型的方法表;
    2. 虚拟机搜索方法签名;
    3. 调用方法。

    1、下列代码输出是什么?为什么输出为 private f()?

    //: polymorphism/PrivateOverride.java
    //Trying to override a private method.
    package polymorphism;
    
    import static net.mindview.util.Print.*;
    
    public class PrivateOverride {
        private void f() {
            print("private f()");
        }
    
        public static void main(String[] args) {
            PrivateOverride po = new Derived();
            po.f();
        }
    }
    
    class Derived extends PrivateOverride {
        public void f() {
            print("public f()");
        }
    } /*
         * Output: private f()
         */// :~
    

    要点:

    • private 默认为 final,不支持覆盖。
    • 理解静态绑定和动态绑定。
    • 编程规范:函数名避免与父类 private 方法相同,以免发生误解。
    • 将 main 方法移到 PrivateOverride 类外会发现 private 方法无法访问。

    2、下列代码输出是什么?为什么?

    
    //: polymorphism/FieldAccess.java
    // Direct field access is determined at compile time.
    class Super {
        public int field = 0;
    
        public int getField() {
            return field;
        }
    }
    
    class Sub extends Super {
        public int field = 1;
    
        public int getField() {
            return field;
        }
    
        public int getSuperField() {
            return super.field;
        }
    }
    
    public class FieldAccess {
        public static void main(String[] args) {
            Super sup = new Sub(); // Upcast
            System.out.println("sup.field = " + sup.field + ", sup.getField() = " + sup.getField());
            Sub sub = new Sub();
            System.out.println("sub.field = " + sub.field + ", sub.getField() = " + sub.getField()
                    + ", sub.getSuperField() = " + sub.getSuperField());
        }
    } /*
         * Output: sup.field = 0, sup.getField() = 1 sub.field = 1, sub.getField() =
         * 1, sub.getSuperField() = 0
         */// :~
    

    要点:

    1. 类中的域是静态绑定的,父类引用直接访问域,会返回父类的值。
    2. 编程规范:域设置为 private,用 getter/setter 访问;避免父类和子类域名相同

    3、下列代码输出是什么?为什么?

    //: polymorphism/StaticPolymorphism.java
    // Static methods are not polymorphic.
    class StaticSuper {
    public static String staticGet() {
    1 Thanks to Randy Nichols for asking this question.
    return "Base staticGet()";
    }
    
        public String dynamicGet() {
            return "Base dynamicGet()";
        }
    }
    
    class StaticSub extends StaticSuper {
        public static String staticGet() {
            return "Derived staticGet()";
        }
    
        public String dynamicGet() {
            return "Derived dynamicGet()";
        }
    }
    
    public class StaticPolymorphism {
        public static void main(String[] args) {
            StaticSuper sup = new StaticSub(); // Upcast
            System.out.println(sup.staticGet());
            System.out.println(sup.dynamicGet());
        }
    } /*
         * Output: Base staticGet() Derived dynamicGet()
         */// :~
    

    要点:

    1. static 方法是静态绑定的

    相关文章

      网友评论

          本文标题:多态:动态绑定

          本文链接:https://www.haomeiwen.com/subject/rxypyxtx.html