24

绑定时间可以分为两种类型:静态和动态。静态绑定和动态绑定有什么区别?

你能举一个简单的例子来进一步说明吗?

4

6 回答 6

28

在最一般的术语中,静态绑定意味着在编译时解析引用。

Animal a = new Animal();
a.Roar(); // The compiler can resolve this method call statically.

动态绑定意味着引用在运行时被解析。

public void MakeSomeNoise(object a) {
   // Things happen...
   ((Animal) a).Roar(); // You won't know if this works until runtime!
}
于 2009-03-13T00:15:59.957 回答
6

这取决于绑定发生的时间:编译时(静态)或运行时(动态)。调用简单类方法时使用静态绑定。当您开始处理类层次结构和虚拟方法时,编译器将开始使用所谓的VTABLE。那时编译器并不确切知道要调用什么方法,它必须等到运行时才能确定要调用的正确方法(这是通过VTABLE完成的)。这称为动态绑定。

有关更多详细信息和参考,请参阅有关虚拟表的Wikipedia 文章。

于 2009-03-13T00:16:49.703 回答
4

我遇到了一个quora用户“Monis Yousuf”的完美答案。他完美地解释了这一点。我把它放在这里是为了其他人。

绑定主要是面向对象编程中与多态性相关的概念。

首先,了解什么是多态。书上说它的意思是“一个名字和多种形式”。没错,但太抽象了。让我们举一个现实生活中的例子。你去看“医生”,医生可能是眼科专家、耳鼻喉科专家、神经外科医生、顺势疗法医生等。

这里的“医生”是一个名字,可以有多种类型;每个人都执行自己的功能。这是现实生活中的多态性。

函数重载:这个概念描述了静态绑定。函数重载可以粗略地定义为,两个或多个同名但签名不同(包括参数个数、参数类型、返回类型不同)的方法(函数)称为重载方法(或函数)。

假设您必须计算矩形和圆形的面积。见下面的代码: -

class CalculateArea {

    private static final double PI = 3.14;

    /* 
       Method to return area of a rectangle 
       Area of rectangle = length X width
    */
    double Area(double length, double width) {
        return (length * width);
    }

    /*
      Method to return area of circle
      Area of circle = π * r * r
    */
    double Area(double radius) {
        return PI * radius * radius;
    }
}

在上面的代码中,有两个方法“Area”具有不同的参数。这种情况称为函数重载。

现在,来到真正的问题:这个静态绑定如何?

当您在代码中调用上述任何函数时,您必须指定要传递的参数。在这种情况下,您将通过:

  • 两个double类型的参数[调用第一个方法,计算是一个矩形]
  • double 类型的单个参数 [将调用第二种方法,计算圆的面积]

因为,在编译时 java 编译器可以确定调用哪个函数,它是编译时(或 STATIC)绑定。

函数覆盖:函数覆盖是一个在继承中显示的概念。大致可以定义为:当父类中存在一个方法,而其子类也有相同的签名方法相同时,称为函数覆盖。[还有更多,但为了简单起见,我写了这个定义]下面的代码会更容易理解。

class ParentClass {
    int show() {
        System.out.println("I am from parent class");
    }
}

class ChildClass extends ParentClass{
    int show() {
        System.out.println("I am from child class");
    }
}

class SomeOtherClass {
    public static void main (String[] s) {
        ParentClass obj = new ChildClass();
        obj.show();
    }
}

在上面的代码中,该方法show()被覆盖,因为父类和子类中都存在相同的签名(和名称)。

在第三个类中SomeOtherClass,一个类型的引用变量(obj)ParentClass保存了 ChildClass 的对象。接下来,方法show() 从同一个引用变量 (obj) 中调用。

同样,同样的问题:这个动态绑定如何?

在编译时,编译器检查 Reference 变量的类型ParentClass并检查该方法show()是否存在于此类中。一旦它检查到这一点,编译就成功了。

现在,当程序运行时,它看到对象是 of ,ChildClass因此,它运行show(). ChildClass由于此决定发生在 RUNTIME,因此称为动态绑定(或运行时多态性)。

原始答案的链接

于 2016-08-16T12:19:20.360 回答
0

静态绑定:是在编译时解析类型、成员和操作的过程。 例如:

Car car = new Car();
car.Drive();

在此示例中,编译器通过在对象上查找无参数Drive方法来执行绑定。car如果没有找到那个方法!搜索带有可选参数的方法,如果没有找到该方法,则再次搜索该方法的基类Car如果没有找到该方法,则再次搜索扩展方法Car类型。如果找不到匹配项,您将收到编译错误!

在这种情况下,绑定是由编译器完成的,并且绑定依赖于静态地知道对象的类型。这使它成为静态绑定。

动态绑定:动态绑定将绑定(解析类型、成员和操作的过程)从编译时推迟到运行时。例如:

dynamic d = new Car();
d.Drive();

动态类型告诉编译器我们期望运行时类型有方法,但我们不能静态d地证明它。由于d是动态的,编译器会将绑定延迟到 d直到 runtimeDrivedDrive

动态绑定对于在编译时我们知道某个函数、操作成员存在但编译器不知道的情况很有用!这通常发生在我们与动态编程语言COM反射进行互操作时。

于 2019-07-03T11:48:12.627 回答
-4

在编译时完成的绑定是静态绑定,在运行时完成的绑定是动态绑定。在静态绑定中,指针的数据类型决定调用哪个方法。但在动态绑定中,对象的数据类型决定调用哪个方法。

于 2012-03-04T13:07:14.870 回答
-5

* 执行时间:-*变量与其值的绑定,以及变量在执行时与特定存储位置的绑定称为执行时间绑定。

它可能有两种类型

  1. 在进入子程序时。
  2. 在执行期间的任意点。

编译时间绑定:-( 翻译时间)它包括以下内容。

  1. 程序员选择的绑定。
  2. 由译者选择的装订。
  3. 加载程序选择的绑定。
于 2012-07-14T05:29:31.580 回答