O que é ligação antecipada e tardia?

75

Eu continuo ouvindo sobre ligação antecipada e atrasada, mas não entendo o que são. Eu encontrei a seguinte explicação que eu não entendo:

Early binding refers to assignment of values to variables during design time whereas late binding refers to assignment of values to variables during run time.

Alguém poderia, por favor, definir os dois tipos de ligação e compará-los?

    
por SAMIR RATHOD 01.06.2013 / 07:00
fonte

7 respostas

82

Existem dois conceitos principais em confusão: ligação e carregamento. Ela é confundida pelo conceito de DataBinding, que está em algum lugar no meio, geralmente fazendo as duas coisas. Depois de considerá-lo, adicionarei mais um conceito, para completar o trecho, despacho.

Tipos

Late Binding : o tipo é desconhecido até que a variável seja exercida durante o tempo de execução; geralmente através de atribuição, mas existem outros meios para coagir um tipo; linguagens tipificadas dinamicamente chamam isso de uma característica subjacente, mas muitas linguagens com tipagem estática possuem algum método para obter ligação tardia

Implementado frequentemente usando tipos dinâmicos [especiais], introspecção / reflexão, sinalizadores e opções de compilador, ou através de métodos virtuais, emprestando e estendendo o despacho dinâmico

Early Binding : o tipo é conhecido antes da variável ser exercida durante o tempo de execução, geralmente através de meios declarativos estáticos

Implementado frequentemente usando tipos primitivos padrão

Funções

Despacho Estático : função conhecida, específica ou sub-rotina em tempo de compilação; não é ambíguo e corresponde à assinatura

Implementado como funções estáticas; nenhum método pode ter a mesma assinatura

Despacho Dinâmico : não é uma função específica ou sub-rotina em tempo de compilação; determinado pelo contexto durante a execução. Existem duas abordagens diferentes para "despacho dinâmico", distinguidas por quais informações contextuais são usadas para selecionar a implementação da função apropriada.

Em único [ dinâmico ] envio , somente o tipo da instância é usado para determinar a implementação da função apropriada. Em linguagens com tipagem estática, o que isso significa na prática é que o tipo de instância decide qual implementação de método é usada, independentemente do tipo de referência indicado quando a variável é declarada / atribuída. Como apenas um único tipo - o tipo da instância do objeto - é usado para inferir a implementação apropriada, essa abordagem é chamada de "despacho único".

Há também várias [ dynamic ] expedição , onde os tipos de parâmetros de entrada também ajudam a determinar qual implementação de função chamar. Como vários tipos - o tipo da instância e o (s) tipo (s) do (s) parâmetro (s) influenciam a implementação do método selecionado, essa abordagem é apelidada de "multiple dispatch".

Implementado como funções virtuais ou abstratas; outras pistas incluem métodos substituídos, ocultos ou sombreados.

NB: Se a sobrecarga de método envolve ou não o despacho dinâmico é específico do idioma. Por exemplo, em Java, os métodos sobrecarregados são despachados estaticamente .

Valores

Lazy Loading : estratégia de inicialização de objetos que adia a atribuição de valor até que seja necessária ; permite que um objeto esteja em um estado essencialmente válido, mas intencionalmente incompleto e aguarde até que os dados sejam necessários antes de carregá-lo; frequentemente considerado particularmente útil para carregar grandes conjuntos de dados ou aguardar recursos externos

Implementado muitas vezes intencionalmente não carregando uma coleção ou lista em um objeto composto durante as chamadas de construtor ou de inicialização até que algum chamador downstream peça para ver o conteúdo dessa coleção (por exemplo, get_value_at, get_all_as, etc). As variações incluem o carregamento de meta informações sobre a coleção (como tamanho ou chaves), mas omitindo os dados reais; também fornece um mecanismo para alguns tempos de execução para fornecer aos desenvolvedores um esquema de implementação de singleton razoavelmente seguro e eficiente

Eager Loading : estratégia de inicialização de objetos que executa imediatamente todas as atribuições de valor para que todos os dados precisem ser concluídos antes de considerar-se em um estado válido.

Implementado com frequência fornecendo um objeto composto com todos os dados conhecidos o mais rápido possível, como durante uma chamada ou inicialização do construtor

Ligação de dados : envolve frequentemente a criação de um link ativo ou mapa entre dois fluxos de informação compatíveis para que as alterações em um sejam refletidas de volta no outro e vice-versa; para ser compatível, eles geralmente precisam ter um tipo de base comum, ou interface

Implementado frequentemente como uma tentativa de fornecer uma sincronização mais clara e consistente entre diferentes aspectos do aplicativo (por exemplo, modelo de exibição para visualização, modelo para controlador, etc.) e fala sobre conceitos como origem e destino, endpoints, bind / unbind, update, e eventos como on_bind, on_property_change, on_explicit, on_out_of_scope

EDIT NOTE: Última edição importante para fornecer uma descrição de exemplos de como isso ocorre com frequência. Exemplos de códigos específicos dependem inteiramente da implementação / tempo de execução / plataforma

    
por 01.06.2013 / 08:32
fonte
26

Qualquer coisa que seja decidida pelo compilador durante a compilação pode se referir a EARLY / COMPILE TIME Binding e tudo o que deve ser decidido em RUNTIME é chamado LATE / Ligação RUNTIME .

Por exemplo,

Método Sobrecarga e Método Sobrescrevendo .

1) Em Sobrecarga de método , suas chamadas de método para os métodos são decididas pelo compilador no sentido de que a função a ser chamada é decidida pelo compilador em tempo de compilação. Portanto, sendo COMEÇAR ANTECIPADAMENTE .

2) No método Overriding, é decidido em RUNTIME qual método será chamado. Por isso, é referenciado como LIGAÇÃO TARDIA .

Tentamos mantê-lo simples e fácil de conseguir. Espero que isso ajude.

    
por 01.06.2013 / 08:36
fonte
9

Ligação tardia é quando o comportamento é avaliado em tempo de execução. É necessário quando você realmente quer determinar como agir baseado em informações que você só tem quando o programa está rodando. O exemplo mais claro na minha opinião é o mecanismo de função virtual, especificamente em C ++.

class A
{
public:
    void f() {}
    virtual void g() {}
};

class B : public A
{
    void f() {}
    virtual void g() {}
};

int main()
{
    A* a = new B;
    a->f();
    a->g();
}

Neste exemplo, a->f() irá realmente chamar void A::f() , porque é inicial (ou estaticamente) ligado e, portanto, o programa em tempo de execução pensa que é apenas um ponteiro para um tipo A variável, enquanto a->g() realmente chamará void B::g() , porque o compilador, vendo g() é virtual, injeta código para procurar o endereço da função correta para chamar em tempo de execução.

    
por 01.06.2013 / 07:57
fonte
5

se você estiver familiarizado com os ponteiros de função, isso seria um exemplo. Funções definidas podem ser consideradas como ligação antecipada. enquanto que se você usar ponteiros de função sua ligação tardia.

  int add(int x,int y)
  {
    return x+y;
  }
  int sub(int x,int y)
  {
      return x-y;
  }


    int main()
    {
     //get user choice
     int(*fp)(int,int);
     //if add
      fp=add;
     //else if sub
     fp=sub;
     cout<<fp(2,2);
    }

aqui funções add e sub são funções (seu endereço é ligado no tempo de compilação-linker)

mas o ponteiro de função é ligação tardia, o fp pode chamar add ou sub, dependendo da escolha do usuário [em tempo de execução].

    
por 01.06.2013 / 07:05
fonte
3

A vinculação antecipada e tardia só faz sentido no contexto de tipos e não da maneira como você está descrevendo. Quase todas as linguagens modernas são digitadas no sentido de que todos os valores possuem tipos fixos. A diferença surge quando olhamos dinamicamente vs linguagens estaticamente tipadas. Em linguagens tipificadas dinamicamente, as variáveis não têm tipos, então elas podem se referir a valores de qualquer tipo e isso significa que quando você chama um método em um objeto referido por alguma variável, a única maneira de determinar se essa chamada é válida ou não é procure a classe para o objeto e veja se esse método realmente existe. Isso permite algumas coisas legais, como adicionar novos métodos a classes em tempo de execução, porque a pesquisa de método real é adiada até o último momento. A maioria das pessoas chama este estado de coisas de ligação tardia.

Em uma linguagem estaticamente tipada, as variáveis têm tipos e, uma vez declaradas, não podem se referir a qualquer valor que não seja do mesmo tipo. Isso não é estritamente verdadeiro, mas vamos assumir isso por enquanto. Agora, se você souber que a variável sempre se referirá apenas a valores de um tipo específico, não há razão para descobrir se uma chamada de método é válida ou não em tempo de execução, pois é possível determinar a validade antes que o código seja executado. Isso é chamado de ligação antecipada.

Um exemplo para demonstrar a ligação tardia no rubi:

a = 1 # a is an integer at this point
a.succ # asking for its successor is valid

class A
  def method_a
    # some code
  end
end

a = A.new
a.method_a # this is also valid
a.succ # this is not valid


class A # we can re-open the class and add a method
  def succ
    # some more code
  end
end
a.succ # now this is valid

A sequência de ações acima não é possível em uma linguagem como Java, onde todos os tipos são corrigidos em tempo de execução.

    
por 01.06.2013 / 07:47
fonte
1

Em vez de lhe dar uma definição acadêmica, tentarei mostrar algumas das diferenças usando um exemplo do mundo real usando o VBA:

Ligação antecipada:

Dim x As FileSystemObject
Set x = New FileSystemObject
Debug.Print x.GetSpecialFolder(0)

Isso requer que uma referência seja definida como o componente "Microsoft Scripting Runtime" no tempo de design . Ele tem a vantagem de receber uma mensagem de erro já em tempo de compilação quando você tem um erro de digitação em FileSystemObject ou nomes de métodos como GetSpecialFolder .

Ligação tardia

Dim x As Object
Set x = CreateObject("Scripting.FileSystemObject")
Debug.Print x.GetSpecialFolder(0)

Isso não requer que uma referência seja definida antecipadamente, a criação da instância e a determinação do tipo ocorrerão apenas em tempo de execução. O compilador não reclamará em tempo de compilação quando você tentar chamar um método inexistente de x , isso levará a um erro em tempo de execução somente quando a linha específica for executada.

Assim, a desvantagem da ligação tardia é que você não tem nenhuma verificação de tipo strong aqui. Mas essa também é a vantagem - digamos que você tenha um componente onde existem várias versões, e cada nova versão fornece algumas funções adicionais. (Um exemplo do mundo real são os componentes do MS Office, como a interface COM do Excel) A ligação tardia permite escrever código que funciona junto com todas essas versões - você pode primeiro determinar a versão específica do componente e, se descobrir que tem apenas uma versão mais antiga disponível, evite executar chamadas de funções que não funcionam com essa versão.

    
por 01.06.2013 / 10:27
fonte
-2

Talvez o exemplo mais comum de ligação tardia seja a resolução de URLs da Internet. Ele suporta sistemas dinâmicos e grandes sistemas sem tentar vincular e vincular todos os sites do mundo antes que você chegue a nenhum, mas, por outro lado, incorrer em alguma sobrecarga (pesquisa de DNS, muito menos roteamento IP) em tempo de execução.

Por essa luz, a maioria das variedades de ligação em ambientes de linguagem é mais ou menos cedo, em tempo de compilação ou tempo de link.

Cada tipo tem custos e benefícios.

    
por 17.01.2016 / 22:48
fonte