Liaison statique et dynamique en Java

Liaison statique et dynamique en Java

1. introduction

Polymorphism permet à un objet de prendre plusieurs formes - lorsqu'une méthode présente un polymorphisme, le compilateur doit mapper le nom de la méthode sur l'implémentation finale.

S'il est mappé au moment de la compilation, il s'agit d'une liaison statique ou anticipée.

S'il est résolu au moment de l'exécution, il s'agit d'une liaison dynamique ou tardive.

2. Comprendre par un code

Lorsqu'une sous-classe étend une super-classe, elle peut réimplémenter les méthodes définies par celle-ci. C'est ce qu'on appelle une méthode surchargée.

Par exemple, créons une superclasseAnimal:

public class Animal {

    static Logger logger = LoggerFactory.getLogger(Animal.class);

    public void makeNoise() {
        logger.info("generic animal noise");
    }

    public void makeNoise(Integer repetitions) {
        while(repetitions != 0) {
            logger.info("generic animal noise countdown " + repetitions);
            repetitions -= 1;
        }
    }
}

Et une sous-classeDog:

public class Dog extends Animal {

    static Logger logger = LoggerFactory.getLogger(Dog.class);

    @Override
    public void makeNoise() {
        logger.info("woof woof!");
    }

}

Lors de la surcharge d'une méthode, comme lesmakeNoise() de la classeAnimal, le compilateur résoudra la méthode et son code au moment de la compilation. This is an example of static binding.

Cependant, si nous affectons un objet de typeDog à une référence de typeAnimal, le compilateur résoudra le mappage de code de fonction lors de l'exécution. C'est une liaison dynamique.

Pour comprendre comment cela fonctionne, écrivons un petit extrait de code pour appeler les classes et ses méthodes:

Animal animal = new Animal();

// calling methods of animal object
animal.makeNoise();
animal.makeNoise(3);

// assigning a dog object to reference of type Animal
Animal dogAnimal = new Dog();

dogAnimal.makeNoise();

The output of the above code will be:
com.example.binding.Animal - generic animal noise
com.example.binding.Animal - generic animal noise countdown 3
com.example.binding.Animal - generic animal noise countdown 2
com.example.binding.Animal - generic animal noise countdown 1
com.example.binding.Dog - woof woof!

Maintenant, créons un cours:

class AnimalActivity {

    public static void eat(Animal animal) {
        System.out.println("Animal is eating");
    }

    public static void eat(Dog dog) {
        System.out.println("Dog is eating");
    }
}

Ajoutons la ligne à la classe principale:

AnimalActivity.eat(dogAnimal);

La sortie serait:

com.example.binding.AnimalActivity - Animal is eating

This example shows that a static function undergoes static binding.

La raison en est que les sous-classes ne peuvent pas remplacer les méthodes statiques. Si la sous-classe implémentait la même méthode, la méthode de la super-classe serait masquée. Similarly, if a method is final or private, the JVM will do a static binding.

Une méthode statique liée n'est pas associée à un objet particulier mais est plutôt appelée surType (classe en Java). L'exécution d'une telle méthode est légèrement plus rapide.

Toute autre méthode est automatiquement une méthode virtuelle en Java par défaut. La machine virtuelle Java résout ces méthodes au moment de l'exécution. Il s'agit d'une liaison dynamique.

L’implémentation exacte dépend de la machine virtuelle Java, mais elle prendrait une approche semblable à C ++, la machine virtuelle recherchant la table virtuelle pour décider de l’objet auquel la méthode serait appelée.

3. Conclusion

La liaison fait partie intégrante d'un langage qui implémente le polymorphisme, il est important de comprendre les implications de la liaison statique et dynamique pour être sûr que nos applications se comportent comme nous le souhaitons.

Avec cette compréhension, toutefois, nous pouvons utiliser efficacement l'héritage de classe ainsi que la surcharge de méthodes.

Comme toujours, le code est disponibleover on GitHub.