В чем разница между ранним и поздним связыванием?

В чем разница между ранним и поздним связыванием?

14.08.2008 02:10:53
Могу ли я сказать, что рано = прямой вызов функции, а поздно = вызов функции через указатель функции? Меня не перестает удивлять то, как у программистов есть способ воспринимать простые концепции и заставлять их казаться более сложными, чем они (как демонстрация интеллекта?). Программирование по своей природе является очень легкой областью изучения, пока вы не приступите к таким вещам, как создание типа с плавающей запятой или разработка компиляторов.
Bob Blogge 18.07.2013 16:53:20
berkay 2.04.2018 14:58:53
7 ОТВЕТОВ
РЕШЕНИЕ

Краткий ответ: раннее (или статическое) связывание относится к привязке во время компиляции, а позднее (или динамическое) связывание относится к привязке во время выполнения (например, когда вы используете отражение).

57
14.08.2008 03:39:22
Но в статье в Википедии о позднем связывании ( en.wikipedia.org/wiki/Late_binding ) говорится, что «позднее связывание часто путают с динамической диспетчеризацией, но есть существенные различия». Так они одинаковые или нет? Если они одинаковые, то эту страницу википедии нужно изменить.
Alexander Bird 1.03.2011 21:15:37
Лучший ответ от stackoverflow здесь stackoverflow.com/questions/484214/early-and-late-binding
Baggers 8.10.2014 06:56:52

Взято непосредственно с http://word.mvps.org/fAQs/InterDev/EarlyvsLateBinding.htm

Существует два способа использования автоматизации (или OLE-автоматизации) для программного управления другим приложением.

Позднее связывание использует CreateObject для создания и экземпляра объекта приложения, которым вы затем можете управлять. Например, чтобы создать новый экземпляр Excel с использованием позднего связывания:

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

С другой стороны, для управления существующим экземпляром Excel (если Excel уже открыт) вы должны использовать GetObject (независимо от того, используете ли вы раннее или позднее связывание):

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

Чтобы использовать раннее связывание, сначала необходимо установить ссылку в своем проекте на приложение, которым вы хотите манипулировать. В редакторе VB любого приложения Office или в самом VB это можно сделать, выбрав «Инструменты + ссылки» и выбрав нужное приложение из списка (например, «Библиотека объектов Microsoft Excel 8.0»).

Чтобы создать новый экземпляр Excel с использованием раннего связывания:

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

В любом случае, между прочим, вы можете сначала попытаться получить существующий экземпляр Excel, и если это возвращает ошибку, вы можете создать новый экземпляр в вашем обработчике ошибок.

6
7.08.2012 02:34:28
Я знаю, что этот ответ старый, и он получен откуда-то еще, но он не точный. Позднее связывание подразумевает использование CreateObject, но CreateObject не обязательно подразумевает позднее связывание. Привязка не применяется к методу создания объекта, а только к тому, как он объявлен. Если вы объявляете свой объект «как приложение Excel.Application», то не имеет значения, как вы его создаете. Я всегда использую CreateObject для создания экземпляров ссылок на объекты во внешних библиотеках, таким образом я могу переключаться между ранним и поздним связыванием и должен переключать только одну строку (не две) - строку, которая объявляет объект.
JimmyPena 14.10.2011 18:24:10

В скомпилированных языках разница очевидна.

Джава:

//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) может быть очень далек от определения метода, и если вы смотрите на определение метода, было бы неплохо увидеть реализацию.

Основным преимуществом позднего связывания является то, что оно облегчает такие вещи, как инверсия контроля, а также некоторые другие виды использования полиморфизма и типизирования утки (если ваш язык поддерживает такие вещи).

18
8.03.2018 04:39:07

В интерпретируемых языках разница немного более тонкая.

Рубин:

# 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 широко использует позднюю привязку для уменьшения объема конфигурации, необходимой для запуска вашего приложения.

3
14.08.2008 02:21:56
Этот пункт применим также к скомпилированным языкам, которые могут включать компоненты, скомпилированные JIT и включенные во время выполнения для реализации плагинов или динамических платформ. Некоторые канонические примеры этого существуют в Java, и, конечно, в Ruby и Python. Экстремальным примером является Erlang, где среда выполнения может загружать две версии любого модуля одновременно для текущих обновлений / понижений. Таким образом, хотя большая часть кода Erlang (большая часть?) Написана как чистые статически типизированные функции, требования времени выполнения требуют позднего связывания и динамических типов под капотом.
zxq9 6.02.2018 03:01:45

Подобный, но более подробный ответ из книги Герберта Шильдта C ++: -

Раннее связывание относится к событиям, которые происходят во время компиляции. По сути, раннее связывание происходит, когда вся информация, необходимая для вызова функции, известна во время компиляции. (Другими словами, раннее связывание означает, что объект и вызов функции связаны во время компиляции.) Примеры раннего связывания включают обычные вызовы функций (включая стандартные функции библиотеки), перегруженные вызовы функций и перегруженные операторы. Основным преимуществом раннего связывания является эффективность. Поскольку вся информация, необходимая для вызова функции, определяется во время компиляции, эти типы вызовов функций очень быстрые.

Противоположностью раннего связывания является позднее связывание. Позднее связывание относится к вызовам функций, которые не разрешаются до времени выполнения. Виртуальные функции используются для позднего связывания. Как вы знаете, когда доступ осуществляется через базовый указатель или ссылку, виртуальная функция, которая фактически вызывается, определяется типом объекта, на который указывает указатель. Поскольку в большинстве случаев это невозможно определить во время компиляции, объект и функция не связаны до времени выполнения. Основным преимуществом позднего связывания является гибкость. В отличие от раннего связывания, позднее связывание позволяет создавать программы, которые могут реагировать на события, происходящие во время выполнения программы, без необходимости создавать большой объем «кода непредвиденных обстоятельств». Имейте в виду, что поскольку вызов функции не разрешается до времени выполнения, позднее связывание может привести к несколько более медленному времени выполнения. Однако сегодня

5
23.05.2015 00:37:47
«объект и функция не связаны до времени выполнения». Это утверждение подразумевает, что объект существует до времени выполнения. Разве объекты не являются объектами времени выполнения? Это класс объекта, который существует во время компиляции. Это можно лучше сформулировать как «вызов функции и ее реализация не связаны до времени выполнения»
programmerravi 22.09.2017 02:17:04
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

При раннем связывании компилятор будет иметь доступ ко всем методам в child и teenager, но при позднем связывании (во время выполнения) он будет проверять методы, которые были переопределены во время выполнения.

Следовательно, method1 (от потомка - раннее связывание) будет переопределен method1 от взрослого во время выполнения (позднее связывание). Затем он реализует method1 от потомка, так как нет метода1 в method1 у подростка.

Обратите внимание, что если у child нет метода method1, код в main не будет компилироваться.

0
22.01.2016 08:41:57

Полиморфизм времени компиляции также называется перегрузкой или ранним связыванием или статическим связыванием, когда у нас одно и то же имя метода с различным поведением. При реализации нескольких прототипов одного и того же метода и различного поведения происходит в нем. Раннее связывание относится к первой компиляции программы. Но в конце связывание объекта происходит во время выполнения программы. Также называется динамическим связыванием или переопределением или полиморфизмом времени выполнения.

0
15.04.2017 03:34:34