Statische und dynamische Bindung in Java

1. Einleitung

Durch Polymorphismus kann ein Objekt mehrere Formen annehmen. Wenn eine Methode Polymorphismus aufweist, muss der Compiler den Namen der Methode der endgültigen Implementierung zuordnen.

Wenn es zur Kompilierungszeit zugeordnet wird, handelt es sich um eine statische oder frühe Bindung.

Wenn es zur Laufzeit aufgelöst wird, spricht man von dynamischer oder später Bindung.

2. Durch einen Code verstehen

Wenn eine Unterklasse eine Oberklasse erweitert, kann sie die von ihr definierten Methoden erneut implementieren. Dies wird als überschreibende Methode bezeichnet.

Erstellen wir zum Beispiel ein Tier der Oberklasse :

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

Und eine Unterklasse Hund :

public class Dog extends Animal { static Logger logger = LoggerFactory.getLogger(Dog.class); @Override public void makeNoise() { logger.info("woof woof!"); } }

Beim Überladen einer Methode wie makeNoise () der Animal- Klasse löst der Compiler die Methode und ihren Code beim Kompilieren auf. Dies ist ein Beispiel für eine statische Bindung.

Wenn wir jedoch einer Referenz vom Typ Animal ein Objekt vom Typ Dog zuweisen, löst der Compiler die Funktionscode-Zuordnung zur Laufzeit auf. Dies ist eine dynamische Bindung.

Um zu verstehen, wie dies funktioniert, schreiben wir ein kleines Code-Snippet, um die Klassen und ihre Methoden aufzurufen:

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.baeldung.binding.Animal - generic animal noise com.baeldung.binding.Animal - generic animal noise countdown 3 com.baeldung.binding.Animal - generic animal noise countdown 2 com.baeldung.binding.Animal - generic animal noise countdown 1 com.baeldung.binding.Dog - woof woof!

Jetzt erstellen wir eine Klasse:

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

Fügen wir diese der Hauptklasse hinzu:

AnimalActivity.eat(dogAnimal);

Die Ausgabe wäre:

com.baeldung.binding.AnimalActivity - Animal is eating

Dieses Beispiel zeigt, dass eine statische Funktion eine statische Bindung eingeht .

Der Grund dafür ist, dass Unterklassen statische Methoden nicht überschreiben können. Wenn die Unterklasse dieselbe Methode implementieren würde, würde sie die Methode der Oberklasse ausblenden. Wenn eine Methode endgültig oder privat ist, führt die JVM eine statische Bindung durch.

Eine statisch gebundene Methode ist keinem bestimmten Objekt zugeordnet, sondern wird für Type (Klasse in Java) aufgerufen . Die Ausführung einer solchen Methode ist geringfügig schneller.

Jede andere Methode ist standardmäßig automatisch eine virtuelle Methode in Java. Die JVM löst solche Methoden zur Laufzeit auf und dies ist eine dynamische Bindung.

Die genaue Implementierung hängt von der JVM ab, es würde jedoch ein C ++ - ähnlicher Ansatz erforderlich sein, bei dem die JVM die virtuelle Tabelle nachschlägt, um zu entscheiden, welches Objekt die Methode aufgerufen werden soll.

3. Fazit

Die Bindung ist ein wesentlicher Bestandteil einer Sprache, die Polymorphismus implementiert. Es ist wichtig, die Auswirkungen der statischen und dynamischen Bindung zu verstehen, um sicherzustellen, dass sich unsere Anwendungen so verhalten, wie wir es möchten.

Mit diesem Verständnis sind wir jedoch in der Lage, die Klassenvererbung sowie die Methodenüberladung effektiv zu nutzen.

Wie immer ist der Code auf GitHub verfügbar.