Qual è la differenza tra Early e Late Binding?

Qual è la differenza tra l’associazione anticipata e tardiva?

La risposta breve è che il legame precoce (o statico) si riferisce al binding in fase di compilazione e il binding tardivo (o dinamico) fa riferimento al binding al runtime (ad esempio quando si utilizza il reflection).

Nelle lingue compilate, la differenza è netta.

Giava:

//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); 

Nel primo esempio, il compilatore può fare ogni sorta di roba ordinata in fase di compilazione. Nel secondo, devi solo sperare che chiunque usi il metodo lo faccia in modo responsabile. (Naturalmente, le JVM più recenti supportano la Class klass structure, che può ridurre notevolmente questo rischio.)

Un altro vantaggio è che gli IDE possono eseguire il hotlink alla definizione della class, poiché è dichiarata proprio lì nel metodo. La chiamata a create_something (Foo) potrebbe essere molto lontana dalla definizione del metodo, e se stai guardando la definizione del metodo, potrebbe essere bello vedere l’implementazione.

Il vantaggio principale del binding tardivo è che rende più semplice l’inversione di controllo, così come certi altri usi del polimorfismo e della tipizzazione delle anatre (se il linguaggio supporta queste cose).

Preso direttamente da http://word.mvps.org/fAQs/InterDev/EarlyvsLateBinding.htm

Esistono due modi per utilizzare Automation (o automazione OLE) per controllare a livello di programmazione un’altra applicazione.

L’associazione tardiva utilizza CreateObject per creare e l’istanza dell’object applicazione, che è ansible controllare. Ad esempio, per creare una nuova istanza di Excel utilizzando l’associazione tardiva:

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

D’altra parte, per manipolare un’istanza esistente di Excel (se Excel è già aperto) si utilizzerà GetObject (indipendentemente dal fatto che si stia utilizzando l’associazione anticipata o tardiva):

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

Per utilizzare l’associazione anticipata, è innanzitutto necessario impostare un riferimento nel progetto per l’applicazione che si desidera manipolare. Nell’Editor VB di qualsiasi applicazione Office, o in VB stesso, puoi farlo selezionando Strumenti + Riferimenti e selezionando l’applicazione desiderata dall’elenco (ad esempio “Libreria oggetti di Microsoft Excel 8.0”).

Per creare una nuova istanza di Excel utilizzando l’associazione anticipata:

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

In entrambi i casi, per inciso, è ansible provare prima a ottenere un’istanza esistente di Excel e, se questo restituisce un errore, è ansible creare una nuova istanza nel gestore degli errori.

Risposta simile ma più dettagliata dal libro C ++ di Herbert Schildt: –

L’associazione anticipata si riferisce a eventi che si verificano in fase di compilazione. In sostanza, l’associazione anticipata si verifica quando tutte le informazioni necessarie per chiamare una funzione sono note al momento della compilazione. (In modo diverso, l’associazione anticipata significa che un object e una chiamata di funzione sono associati durante la compilazione.) Esempi di associazione anticipata includono chiamate di funzioni normali (incluse funzioni di libreria standard), chiamate di funzioni sovraccaricate e operatori sovraccaricati. Il principale vantaggio per l’associazione anticipata è l’efficienza. Poiché tutte le informazioni necessarie per chiamare una funzione sono determinate al momento della compilazione, questi tipi di chiamate di funzione sono molto veloci.

L’opposto dell’associazione anticipata è l’associazione tardiva. L’associazione tardiva si riferisce alle chiamate di funzione che non vengono risolte fino al runtime. Le funzioni virtuali vengono utilizzate per ottenere un legame tardivo. Come sapete, quando l’accesso avviene tramite un puntatore o riferimento di base, la funzione virtuale effettivamente chiamata è determinata dal tipo di object puntato dal puntatore. Poiché nella maggior parte dei casi questo non può essere determinato in fase di compilazione, l’object e la funzione non sono collegati fino al runtime. Il vantaggio principale del binding tardivo è la flessibilità. A differenza del binding anticipato, l’associazione tardiva consente di creare programmi in grado di rispondere agli eventi che si verificano durante l’esecuzione del programma senza dover creare una grande quantità di “codice di emergenza”. Tieni presente che, poiché una chiamata di funzione non viene risolta fino al runtime, l’associazione tardiva può ridurre i tempi di esecuzione. Tuttavia oggi i computer veloci hanno ridotto in modo significativo i tempi di esecuzione relativi all’associazione tardiva.

Nelle lingue interpretate, la differenza è un po ‘più sottile.

Rubino:

 # 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) 

Perché Ruby è (generalmente) non compilato, non c’è un compilatore per fare le cose di prima class. La crescita di JRuby significa che al momento viene compilato più Ruby, rendendolo più simile a Java, sopra.

Il problema con gli IDE è ancora valido: una piattaforma come Eclipse può cercare le definizioni di class se le si codifica, ma non è ansible se le si lascia al chiamante.

L’inversione di controllo non è molto popolare in Ruby, probabilmente a causa della sua estrema flessibilità di runtime, ma Rails fa un grande uso del late binding per ridurre la quantità di configurazione necessaria per far funzionare la tua applicazione.

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

Questo verrà stampato

 adult1 child1 

Nelle prime fasi di binding il compilatore avrà accesso a tutti i metodi in child e teenager ma in late binding (in fase di esecuzione), controllerà i metodi che vengono sovrascritti in fase di runtime.

Quindi il metodo1 (da child – early binding) verrà sovrascritto dal metodo1 da adult at runtime (late binding) Quindi implementerà method1 dal child poiché non esiste un metodo1 in method1 in adolescente.

Si noti che se il figlio non avesse un metodo1 allora il codice nel main non sarebbe compilato.

Il polimorfismo del tempo di compilazione viene anche chiamato overloading o early binding o static binding quando abbiamo lo stesso nome di metodo con comportamenti diversi. Implementando il prototipo multiplo dello stesso metodo e in esso si verifica un comportamento diverso. L’associazione anticipata fa riferimento alla prima compilazione del programma. Ma nel tardo object vincolante il runtime si verifica nel programma. Chiamato anche come Dynamic binding o overriding o Runtime polymorphism.