首页 > 解决方案 > 动态绑定条件 Java

问题描述

我的教授已经给出了一些关于何时在 java 中发生动态绑定的信息,但是在阅读了许多关于堆栈溢出和其他网站的帖子后,我不确定我是否得到了正确的信息。我的教授在他的讲义中指出,在以下情况下需要动态绑定:

1) 一个变量被声明为有一个超类作为它的类型,并且

2)有不止一种可能的多态方法可以在变量类型及其子类之间运行

我不确定条件 1),因为我一直在阅读的所有地方都指出,只要有方法覆盖,就需要动态绑定。一个例子:

public class Polygon{
    public void getPerimeter(){
        System.out.println("Polygon method")
    }
}

public class Rectangle() extends Polygon{
    public void getPerimeter(){
        System.out.println("Rectangle method")

    }
}


public static void main(String[] args){
    Rectangle a = new Rectangle();
    a.getPerimeter();
}

这段代码需要动态绑定吗?Rectangle 不是超类,因此不满足条件 1)。但是,Rectangle 中的方法覆盖了超类 Polygon 中的方法。编译器如何知道要运行哪个方法?

标签: java

解决方案


在Java中,多态性由两个方面组成:

  • 类型继承:使用超类型类型的引用指向子类型类型的实例(例如:)Polygon p = new Rectangle()
  • 动态绑定:在运行时将方法签名绑定到方法实现,基于对象的实际类型(例如: for p.getPerimeter()getParamater最特定于实际类型的方法p被调用)。

由于在您的示例中,您在定义时没有使用超类类型,Rectangle因此您没有使用多态性。

如果你想使用多态,重构你的代码如下:

public static void main(String[] args) {
    // using a supertype reference
    Polygon a = new Rectangle();
    /** 
        there are two methods available here, the one inherited from Polygon and 
        the one Rectangle overrides. Dynamic binding ensures the right method gets 
        picked up at runtime, based on the actual type of the Polygon object 
        (which in this case in Rectangle)
    */
    a.getPerimeter();
}

您可能会争辩说即使在您的示例中也会发生动态绑定(因为在运行时会选择正确的实现),但是以这种方式使用它会破坏动态绑定的目的(因为如果您将引用定义为与实际对象相同的类型,你总是会得到一个且只有一个实现)。

您的教授可能指的是多态性而不是动态绑定


推荐阅读