Dynamische Bindung
Der Begriff dynamische Bindung (englisch dynamic binding) bezeichnet die verzögerte Bindung eines Namens an ein Objekt, das diesen Namen implementiert;[1] die Bindung des Namens an z. B. eine konkrete Variable, Funktion oder Methode erfolgt erst zum Zeitpunkt der Anweisungsausführung, d. h. zur Laufzeit. Dynamische Bindung ist generell eine Eigenschaft schwach typisierter Programmiersprachen, die mittlerweile auch von streng typisierten Programmiersprachen eingesetzt wird. Historisch wurde dynamische Bindung mit den Lisp-Dialekten zuerst eingeführt.[2]
Anwendungen
Im Kontext der objektorientierten Programmierung wird dynamische Bindung z. B. zur laufzeitabhängigen Auswahl der Implementierung von polymorphen Methoden eingesetzt. Erst beim Aufruf einer polymorphen Methode für ein Objekt zur Laufzeit wird anhand seines tatsächlichen Objekttyps (Klasse) die entsprechende Implementierung dieser Methode ermittelt (z. B. mittels Run-Time Type Information, RTTI) und aufgerufen. Dynamische Bindung ermöglicht es, Objektverhalten in Form von Methoden im Softwareentwurf z. B. in Basisklassen abstrakt zu definieren und die Implementierungen spezifisch in den abgeleiteten Klassen vorzunehmen.
Auf dem Gebiet der Kontext-orientierte Programmierung (Context-Oriented Programming, COP) wird dynamische Binding als genereller Wirkmechanismus eingesetzt, um zur Laufzeit Objektverhalten dynamisch zu komponieren und auszuführen. „The COP paradigm tackles the issue of developing context-aware systems at the language-level, introducing ad hoc language abstractions to manage adaptations modularization and their dynamic activation.“[3]
Funktionsweise am Beispiel polymorpher Methoden
Bei Klassenhierarchien kann eine Variable, deren Typ auf eine bestimmte Klasse festgelegt ist, auch Objekte von abgeleiteten Klassen referenzieren, für die Methoden aus der Basisklasse überschrieben sein können. Wird für ein über eine Variable referenziertes Objekt eine polymorphe Methode (auch virtuelle Methode genannt) aufgerufen, wird zum Aufrufzeitpunkt erst der tatsächliche Objekttyp ermittelt und dann die Methodenimplementierung der entsprechenden Klasse aufgerufen. Methodenüberladung bildet eine zentrale Funktionalität der Polymorphie.
Klassen können explizit festlegen, dass bestimmte Methoden von abgeleiteten Klassen entweder nicht überschrieben werden dürfen (z. B. Methoden mit dem Zusatz „final“ in C++) oder überschrieben werden müssen (z. B. rein-virtuelle Methoden einer Basisklasse in C++). Beispielsweise kann in einer abstrakten Basisklasse explizit ein Interface in Form polymorpher Methoden festgelegt werden, ohne dabei zwingend schon eine Implementierung in der abstrakten Basisklasse angeben zu müssen. Eine Klasse muss alle polymorphen Methoden einschließlich jener der Basisklassen implementieren, um instanziierungsfähig zu sein.
Klassen können Methoden enthalten, die explizit nicht polymorph sind; sie werden als statisch gebundene Methoden bezeichnet. Viele objektorientierte Programmiersprachen erlauben für jede Methode einzeln festzulegen, ob statische oder dynamische Bindung anzuwenden ist; diese Eigenschaft wird mitvererbt.
Die dynamische Bindung ist für die objektorientierte Programmierung wesentlich, da die Flexibilität und Ausdrucksstärke der Vererbung erst dadurch möglich wird. Dynamische Bindung ermöglicht es beispielsweise zu einem späteren Zeitpunkt eine Software zu erweitern, in dem spezialisierte Klassen entwickelt und eingefügt werden, die polymorphe Methoden spezifisch implementieren, ohne dass dabei die restliche Software überarbeitet werden muss.
Implementierung
Die Implementierung des Mechanismus zum dynamischen Binden ist programmiersprachenabhängig. Das dynamische Binden kann auf zwei unterschiedlichen Arten implementiert werden.
Virtual Method Table
Der Compiler legt für jeden Typ mit virtuellen Methoden eine Tabelle virtueller Methoden an, die Referenzen auf die aufzurufenden Methoden enthält.
Dispatch Tree
Der Compiler fügt bei jedem Aufruf einer dynamischen Methode eine Verzweigung ein, die anhand des Objekttyps die jeweils richtige Methode auswählt.
Beispiel
Ein typisches Beispiel zu dynamischer Bindung in Java:
import java.util.*;
class Saeugetier {
void steckbrief() {
System.out.println("Ich bin ein Säugetier.");
}
}
class Gepard extends Saeugetier {
void steckbrief() {
System.out.println("Ich bin ein Gepard.");
}
}
class Elefant extends Saeugetier {
void steckbrief() {
System.out.println("Ich bin ein Elefant.");
}
}
public class DynamischeBindungBeispiel {
public static void main(String[] args) {
List<Saeugetier> tiere = new ArrayList<Saeugetier>();
tiere.add(new Saeugetier());
tiere.add(new Gepard());
tiere.add(new Elefant());
for (Saeugetier tier: tiere) {
tier.steckbrief();
}
}
}
Ausgabe
Ich bin ein Säugetier.
Ich bin ein Gepard.
Ich bin ein Elefant.
Einzelnachweise
- Rex E. Gantenbein: Dynamic binding in strongly typed programming languages. Elsevier, 1991, S. 14(1):31–38, doi:10.1016/0164-1212(91)90086-L.
- Luc Moreau: A Syntactic Theory of Dynamic Binding. Springer, Higher-Order and Symbolic Computation, 1998, S. 11:233–279, doi:10.1023/A:1010087314987.
- Guido Salvaneschi, Carlo Ghezzi, Matteo Pradella: Context-oriented programming: A software engineering perspective. Elsevier, Journal of Systems and Software, 2012, S. 85(8):1801–1817, doi:10.1016/j.jss.2012.03.024.