动态,静态和后期绑定有什么区别?

时间:2014-03-15 18:19:56

标签: c++ ios objective-c oop object-oriented-analysis

我正在通过Apple的Object-Oriented Programming in Objective-C指南。在动态主题 - >动态绑定的主题下,有三个概念:

  1. 动态绑定
  2. 晚期绑定
  3. 静态绑定
  4. 我几乎了解动态和后期绑定之间的区别,但静态绑定会让人感到困惑。有人可以用Objective-C或C ++中的例子解释这三个概念之间的差异吗?

    注意:在您考虑将此问题标记为重复之前,没有任何问题可以同时描述这三个问题。

1 个答案:

答案 0 :(得分:7)

静态绑定:是在编译时确定所引用项目的位置。在(目标 - )C(++)中,对函数的调用是静态绑定的;例如,库函数fabsNSLog。在这些语言中,对变量的引用也是静态的; 正在引用的变量在编译时完全确定。静态绑定在运行时不会失败,无法确定静态绑定引用引用的是编译时错误。

后期绑定:这是在运行时确定所引用的确切项目的位置。当一种语言支持继承/子类型,其中类型T可以是类型S的子类型/子/子类(术语取决于语言)时,这通常(但不总是)出现。这意味着类型T的值具有所有类型S的值的属性,以及包含方法的面向对象语言的属性,并且类型T的值可以被视为类型S的值。一个Java示例:

TextComponent t; // a reference to a value of type TextComponent OR any of
                 // its subclasses, such as TextArea or TextField
Color c = t.getBackground(); // a call to TextComponent's getBackground method or
                             // TextArea's getBackground method etc.

调用哪个 getBackground方法直到运行时才确定,并且取决于引用的值t的类型。但是必须getBackground方法,因为t只能引用类型为TextComponent或其子类型之一的值。实际上,当编译器编译此片段时,TextComponent的所有子类型可能都不知道,但是无关紧要,因为子类型保证每个都有getBackground方法。因此,与静态绑定一样,后期绑定也不会在运行时失败。

动态绑定:这是一个超越后期绑定的步骤,它将留给运行时以确定引用的项是否存在。 Objective-C中的一个简单示例:

id anyObject; // this can hold a reference to any Objective-C object

NSUInteger len = [anyObject length]; // TRY to call a method length on the object
                                     // referenced by anyObject. If at runtime this is,
                                     // say, an NSString or NSMutableString value it will
                                     // succeed. However if it is, say, an NSNumber value
                                     // it will FAIL

与后期绑定一样,直到运行时才会确定被调用的实际方法;然而,与后期绑定不同,这种方法是否存在也留给了运行时。因此,与静态和后期绑定不同,动态绑定可能在运行时失败

正如您可能会问的那样:由于可能存在运行时错误,许多语言根本不支持动态绑定 - 它不适用于安全关键软件,但适用于快速原型设计。然而,它确实允许以其他方式更难以完成的设计,因此某些语言会像Objective-C一样,并且这些语言的用户必须接受权力带来的责任。 Xcode / Clang编译器竭尽全力进行尽可能多的静态类型检查,大多数Objective-C代码尽可能精确地使用类型。