【问题标题】:Is this true about late binding?关于后期绑定,这是真的吗?
【发布时间】:2010-10-01 02:10:57
【问题描述】:

我在“Polymorphism”一章的“Thinking in java”中读到了“后期绑定”的概念,我只是想知道我对这个概念的理解是否属实

例如,过程语言知道在运行时之前要执行的函数在哪里

if(condition){func1();}else{func2();}

所以每个可能的函数的地址在程序运行之前是准确知道的,所以它很容易编译,但是在 OOLs 中检查这段代码,,

makeItSpeak(Animal a ){
  a.speak();
}

虽然 a 可能是 dog 、 cat 或任何其他 Animal 类型,并且因为我们在运行时初始化对象,所以我们必须传递在运行时运行 speak 的参数,所以这是后期绑定,它发生在运行时 ....

这是真的吗??

【问题讨论】:

    标签: java polymorphism late-binding


    【解决方案1】:

    是的,它是使用virtual method table 实现的。

    在您的示例中,speak() 是一个没有物理地址的虚拟(抽象)方法。在运行时,根据具体的Animal子类的类型,运行时通过引用虚方法表来确定要调用speak()的哪个实现。

    【讨论】:

      【解决方案2】:

      是的。例如,

      class A {
        void a() { System.out.println("A"); }
      }
      
      class B extends A {
        void a() { System.out.println("B"); }
      }
      
      class C {
        public static void main (String[] args) {
          A anA = new B();
          anA.a();  // This will print B
        }
      }
      

      尽管变量 anA 是 A 类型,但实例是 B,只能在运行时确定。

      此规则中的陷阱是静态方法,它们在编译时被绑定,所以要小心。

      【讨论】:

        【解决方案3】:

        是的,你是对的。在您给出的示例中,要调用的正确 speak() 取决于运行时已知的对象类型。仅当您将方法声明为 final 时,它才会受到早期绑定。

        【讨论】:

        • 是的,因为在这种情况下我们提前知道了方法的地址,原因是我们知道想要的方法是超类的方法,是吗?
        • @3m masr:当您将方法声明为最终方法时,您要确保该方法不会被进一步覆盖。因此不存在将使用什么对象句柄的问题,因此编译器将进行优化。
        • 这仅适用于声明 final 关键字及其后代的类型。如果 B 扩展了 A,A 定义了一个方法 foo() 并且 B 用最终实现覆盖它,那么当在运行时遇到 A a.foo() 时,仍然需要后期绑定。
        【解决方案4】:

        是的,你没看错。它使代码更具可扩展性和功能性。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-07-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-05-16
          • 1970-01-01
          相关资源
          最近更新 更多