早期和晚期绑定有什么区别?

早期和晚期绑定有什么区别?

简单的答案是,早期(或静态)绑定是指编译时绑定,后期(或dynamic)绑定是指运行时绑定(例如,当您使用reflection)。

在编译语言中,差异是十分明显的。

Java的:

//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取得;

有两种方法使用自动化(或OLE自动化)以编程方式控制另一个应用程序。

后期绑定使用CreateObject创build应用程序对象的实例,然后您可以控制该对象。 例如,要使用迟绑定来创build一个新的Excel实例:

  Dim oXL As Object Set oXL = CreateObject("Excel.Application") 

另一方面,要操纵Excel的现有实例(如果Excel已经打开),您可以使用GetObject(无论您使用的是早期还是晚期绑定):

  Dim oXL As Object Set oXL = GetObject(, "Excel.Application") 

要使用早期绑定,首先需要在项目中将引用设置为要操作的应用程序。 在任何Office应用程序的VB编辑器中,或在VB本身中,通过select工具+引用,然后从列表中select所需的应用程序(例如“Microsoft Excel 8.0对象库”)来执行此操作。

使用早期绑定来创buildExcel的新实例:

  Dim oXL As Excel.Application Set oXL = New Excel.Application 

无论哪种情况,顺便说一句,您可以先尝试获取Excel的现有实例,如果返回错误,则可以在error handling程序中创build新实例。

Herbert Schildt C ++书中类似但更详细的答案:

早期绑定是指在编译时发生的事件。 实际上,当编译时知道调用函数所需的所有信息时,就会发生早期绑定。 (换句话说,早期绑定意味着一个对象和一个函数调用在编译期间被绑定)。早期绑定的例子包括正常的函数调用(包括标准库函数),重载函数调用和重载操作符。 早期绑定的主要优点是效率。 因为调用函数所需的所有信息都是在编译时确定的,所以这些types的函数调用非常快。

早期结合的反面是晚期结合。 后期绑定是指直到运行时才parsing的函数调用。 虚拟function用于实现后期绑定。 如您所知,当通过基指针或引用进行访问时,实际调用的虚函数是由指针指向的对象的types决定的。 因为在大多数情况下这不能在编译时确定,对象和函数直到运行时才会被链接。 后期绑定的主要优点是灵活性。 与早期绑定不同,后期绑定允许您创build程序,以响应在程序执行时发生的事件,而不必创build大量的“应急代码”。 请记住,因为函数调用在运行时间之前不能parsing,所以后期绑定可能会使执行时间稍微慢一点。 但是今天,快速计算机已经大大减less了与后期绑定有关的执行时间。

在解释型语言中,差别更微妙一些。

ruby:

 # 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被编译,尽pipe如此,使得它更像上面的Java。

IDE的问题仍然存在:像Eclipse这样的平台可以查找类定义,如果你对它们进行硬编码的话,但是如果把它们留给调用者的话就不行。

Ruby中的反转控制并不是非常受欢迎,可能是因为它具有极高的运行时间灵活性,但是Rails很好地利用了后期绑定来减less使应用程序运行所需的configuration数量。

后期绑定或dynamic绑定是一种计算机编程机制,其中在运行时通过名称查找在对象上调用的方法。

在早期绑定或静态绑定的情况下,编译阶段将修复所有types的variables和expression式。 这通常作为虚拟方法表(“v-表”)中的偏移量存储在编译的程序中,并且非常有效。 通过后期绑定,编译器没有足够的信息来validation方法是否存在,更不用说绑定到v表上的特定插槽。 而是在运行时按名称查找该方法。

 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(); } 

这将打印出来

 adult1 child1 

在早期的绑定中,编译器将有权访问孩子和青less年中的所有方法,但在后期绑定(在运行时),它将检查在运行时被覆盖的方法。

因此,方法1(从小孩 – 早期绑定)将由运行时的成年人的方法1(后期绑定)覆盖。然后,它将从子项实现方法1,因为在青less年方法1中没有方法1。

请注意,如果孩子没有method1,那么main中的代码就不会编译。

编译时多态也称为重载或早期绑定或静态绑定,当我们使用不同行为的方法名称相同时。 通过实现相同方法的多个原型,并在其中发生不同的行为。 早期绑定是指程序的第一次编译。 但在后期绑定对象是运行时发生在程序中。 也称为dynamic绑定或覆盖或运行时多态。