早期和晚期绑定之间有什么区别?
简短的答案是,早期(或静态)绑定是指编译时绑定,而后期(或动态)绑定是指运行时绑定(例如,当您使用反射时)。
在编译语言中,区别是明显的。
Java:
1 2 3 4 5 6 7 8 9 10 11
| //early binding:
public create_a_foo(*args) {
return new Foo(args)
}
my_foo = create_a_foo();
//late binding:
public create_something(Class klass, *args) {
klass.new_instance(args)
}
my_foo = create_something(Foo); |
在第一个示例中,编译器可以在编译时完成各种巧妙的工作。第二,您只希望希望使用该方法的人做到负责任。 (当然,较新的JVM支持Class<? extends Foo> klass结构,这可以大大降低这种风险。)
另一个好处是,IDE可以热链接到类定义,因为它是在方法中声明的。对create_something(Foo)的调用可能与方法定义相去甚远,如果您正在查看方法定义,那么可能很高兴看到实现。
后期绑定的主要优点是,它使控制反转等操作以及多态性和鸭子类型的某些其他用法(如果您的语言支持)更加容易。
直接取自http://word.mvps.org/fAQs/InterDev/EarlyvsLateBinding.htm
There are two ways to use Automation (or OLE Automation) to
programmatically control another application.
Late binding uses CreateObject to create and instance of the
application object, which you can then control. For example, to create
a new instance of Excel using late binding:
1 2
| Dim oXL As Object
Set oXL = CreateObject("Excel.Application") |
On the other hand, to manipulate an existing instance of Excel (if
Excel is already open) you would use GetObject (regardless whether
you're using early or late binding):
1 2
| Dim oXL As Object
Set oXL = GetObject(,"Excel.Application") |
To use early binding, you first need to set a reference in your
project to the application you want to manipulate. In the VB Editor of
any Office application, or in VB itself, you do this by selecting
Tools + References, and selecting the application you want from the
list (e.g."Microsoft Excel 8.0 Object Library").
To create a new instance of Excel using early binding:
1 2
| Dim oXL As Excel.Application
Set oXL = New Excel.Application |
In either case, incidentally, you can first try to get an existing
instance of Excel, and if that returns an error, you can create a new
instance in your error handler.
Herbert Schildt C ++书中类似但更详细的答案:
早期绑定是指在编译时发生的事件。本质上,当在编译时知道调用函数所需的所有信息时,就会发生早期绑定。 (换句话说,早期绑定意味着在编译过程中绑定了对象和函数调用。)早期绑定的示例包括普通函数调用(包括标准库函数),重载函数调用和重载运算符。早期绑定的主要优点是效率。因为调用函数所需的所有信息都是在编译时确定的,所以这些类型的函数调用非常快。
早期绑定的反义词是后期绑定。后期绑定是指
运行直到运行时才解决的调用。虚函数用于实现后期绑定。如您所知,当通过基本指针或引用进行访问时,实际调用的虚函数由指针指向的对象类型因为在大多数情况下无法在编译时确定,所以直到运行时才链接对象和函数。后期绑定的主要优点是灵活性。与早期绑定不同,后期绑定使您可以创建可以响应程序执行过程中发生的事件的程序,而不必创建
大量的"应急代码"。请记住,由于函数调用要等到运行时才能解决,因此后期绑定可能会使执行时间变慢。
但是,如今,快速计算机已大大减少了与后期绑定有关的执行时间。
在解释语言中,差异稍微有些微妙。
红宝石:
1 2 3 4 5 6 7 8 9 10 11
| # early binding:
def create_a_foo(*args)
Foo.new(*args)
end
my_foo = create_a_foo
# late binding:
def create_something(klass, *args)
klass.new(*args)
end
my_foo = create_something(Foo) |
因为(通常)不对Ruby进行编译,所以没有编译器可以完成漂亮的前期工作。 JRuby的增长意味着这些天编译了更多的Ruby,从而使其行为更像上面的Java。
IDE的问题仍然存在:像Eclipse这样的平台可以在您对类定义进行硬编码时查找类定义,但如果将其交给调用者则无法查找。
控制反转在Ruby中并不十分流行,可能是因为它具有极高的运行时灵活性,但是Rails充分利用了后期绑定来减少启动应用程序所需的配置量。
当我们具有相同的方法名称且具有不同的行为时,编译时多态也称为重载,早期绑定或静态绑定。 通过实现相同方法的多个原型,将在其中发生不同的行为。 早期绑定是指程序的首次编译。
但是在后期绑定对象中,运行时发生在程序中。 也称为动态绑定或覆盖或运行时多态。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| public class child()
{ public void method1()
{ System.out.println("child1");
}
public void method2()
{ System.out.println("child2");
}
}
public class teenager extends child()
{ public void method3()
{ System.out.println("teenager3");
}
}
public class adult extends teenager()
{
public void method1()
{ System.out.println("adult1);
super.method1();
}
}
//In java
public static void main(String []args)
{ ((teenager)var).method1();
} |
这将打印出来
在早期绑定中,编译器将可以访问所有方法
在儿童和青少年中
但在后期绑定(在运行时)中,它将检查被覆盖的方法
在运行时。
因此,method1(来自子级-早期绑定)将在运行时被method1来自成人覆盖(后期绑定)
然后,由于少年中的method1中没有method1,因此它将从孩子那里实现method1。
注意,如果child没有method1,则main中的代码将无法编译。