Enllaç dinàmic

procés de selecció de la implementació d'una operació polimòrfica (mètode o funció) a cridar en temps d'execució


En informàtica, l'enllaç dinàmic és el procés de seleccionar quina implementació d'una operació polimòrfica (mètode o funció) cal cridar en temps d'execució. S'utilitza habitualment i es considera una característica principal dels llenguatges i sistemes de programació orientada a objectes (OOP).[1]

Els sistemes orientats a objectes modelen un problema com un conjunt d'objectes interactius que promulguen operacions a les quals es fa referència pel seu nom. El polimorfisme és el fenomen en què objectes una mica intercanviables cadascú exposen una operació del mateix nom però possiblement diferent en comportament. Com a exemple, aFileObjecte i aDatabaseEls dos objectes tenen aStoreRecordMètode que es pot utilitzar per escriure un registre de personal a l'emmagatzematge. Les seves implementacions són diferents. Un programa conté una referència a un objecte que pot ser aFile objecte o aDatabaseObjecte. El que és pot haver estat determinat per una configuració de temps d'execució i, en aquesta etapa, és possible que el programa no sàpiga o no importa quin. Quan el programa cridaStoreRecord a l'objecte, alguna cosa ha de triar quin comportament es promulga. Si un pensa que la POO com envia missatges a objectes, en aquest exemple el programa envia unStoreRecord missatge a un objecte de tipus desconegut, deixant al sistema de suport en temps d'execució enviar el missatge a l'objecte correcte. L'objecte actua qualsevol comportament que implementi.[2]

L'enllaç dinàmic contrasta amb l'enllaç estàtic, en el qual la implementació d'una operació polimòrfica es selecciona en temps de compilació. El propòsit de l'enllaç dinàmic és ajornar la selecció d'una implementació adequada fins que es conegui el tipus de temps d'execució d'un paràmetre (o diversos paràmetres).[3]

L'enllaç dinàmic és diferent de l'enquadernació tardana (també coneguda com a vinculació dinàmica). L'enllaç de nom associa un nom a una operació. Una operació polimòrfica té diverses implementacions, totes associades amb el mateix nom. Els enllaços es poden fer en temps de compilació o (amb enllaç tardà) en temps d'execució. Amb l'enllaç dinàmic, s'escull una implementació particular d'una operació en temps d'execució. Tot i que l'enllaç dinàmic no implica una vinculació tardana, l'enllaç tardà implica un despatx dinàmic, ja que la implementació d'una operació d'enllaç tardà no es coneix fins al moment d'execució.[4]

Enllaç únic i múltiple modifica

L'elecció de la versió d'un mètode a cridar es pot basar en un únic objecte o en una combinació d'objectes. El primer s'anomena enllaç únic i és compatible directament amb llenguatges comuns orientats a objectes com Smalltalk, C++, Java, C#, Objective-C, Swift, JavaScript i Python. En aquests i en llenguatges similars, es pot anomenar un mètode de divisió amb una sintaxi que s'assembla.

dividend.divide(divisor)  # dividend / divisor

on els paràmetres són opcionals. Això es pensa com l'enllaç d'un missatge anomenatdivide amb paràmetredivisor adividend. Es triarà una implementació basant-se només endividendtipus de (potser racional, coma flotant, matriu), sense tenir en compte el tipus o valor dedivisor.

Per contra, alguns llenguatges distribueixen mètodes o funcions basats en la combinació d'operands; en el cas de la divisió, els tipus de ladividend idivisor junts determinen quindividees realitzarà l'operació. Això es coneix com a enllaç múltiple. Exemples d'idiomes que admeten l'enllaç múltiple són Common Lisp, Dylan i Julia.

Mecanismes dinàmics d'enllaç modifica

Un llenguatge es pot implementar amb diferents mecanismes d'enllaç dinàmic. Les opcions del mecanisme d'enllaç dinàmic que ofereix un llenguatge alteren en gran manera els paradigmes de programació que estan disponibles o són més naturals d'utilitzar en un llenguatge determinat. Normalment, en un llenguatge escrit, el mecanisme d'enllaç s'efectuarà en funció del tipus d'arguments (el més habitual es basa en el tipus de receptor d'un missatge). Els idiomes amb sistemes d'escriptura febles o sense mecanografia solen portar una taula d'enllaç com a part de les dades d'objecte de cada objecte. Això permet un comportament de la instància, ja que cada instància pot assignar un missatge determinat a un mètode independent.

Implementació C++ modifica

C++ utilitza l'enllaç primerenc i ofereix enllaç tant dinàmic com estàtic. La forma d'enllaç per defecte és estàtica. Per obtenir un enllaç dinàmic, el programador ha de declarar un mètode comvirtual.

Els compiladors de C++ solen implementar l'enllaç dinàmic amb una estructura de dades anomenada taula de funcions virtuals (vtable) que defineix l'assignació de nom a implementació per a una classe determinada com un conjunt de punters de funció membre. Aquest és purament un detall d'implementació, ja que l'especificació C++ no esmenta vtables. Les instàncies d'aquest tipus emmagatzemaran un punter a aquesta taula com a part de les seves dades d'instància, cosa que complica els escenaris quan s'utilitza l'herència múltiple. Com que C++ no admet l'enllaç tardà, la taula virtual d'un objecte C++ no es pot modificar en temps d'execució, la qual cosa limita el conjunt potencial d'objectius d'enllaç a un conjunt finit escollit en temps de compilació.

Exemple en Python modifica

class Cat:
    def speak(self):
        print("Meow")

class Dog:
    def speak(self):
        print("Woof")


def speak(pet):
    # Dynamically dispatches the speak method
    # pet can either be an instance of Cat or Dog
    pet.speak()

cat = Cat()
speak(cat)
dog = Dog()
speak(dog)

Exemple en C++ modifica

#include <iostream>

// make Pet an abstract virtual base class
class Pet {
public:
    virtual void speak() = 0;
};

class Dog : public Pet {
public:
    void speak() override
    {
        std::cout << "Woof!\n";
    }
};

class Cat : public Pet {
public:
    void speak() override
    {
        std::cout << "Meow!\n";
    }
};

// speak() will be able to accept anything deriving from Pet
void speak(Pet& pet)
{
    pet.speak();
}

int main()
{
    Dog fido;
    Cat simba;
    speak(fido);
    speak(simba);
    return 0;
}

Referències modifica

  1. «Dynamic Method Dispatch or Runtime Polymorphism in Java» (en anglès americà), 24-03-2017. [Consulta: 24 desembre 2023].
  2. «What is dynamic method dispatch and how does it relate to inheritance?» (en anglès). [Consulta: 24 desembre 2023].
  3. «62. Dynamic dispatch - The Object Oriented Way» (en anglès). [Consulta: 24 desembre 2023].
  4. «Dynamic dispatch - CodeDocs» (en anglès). [Consulta: 24 desembre 2023].