Skip to content
IRC-Coding IRC-Coding
Dispatch Dynamic Binding Single Dispatch Double Dispatch Visitor Pattern

OOP Dispatch: Dynamic Binding, Single & Double Dispatch

Dispatch selects method implementations at runtime. Single dispatch, double dispatch, Visitor Pattern, and vtable explained with examples.

S

schutzgeist

2 min read

OOP Dispatch: Dynamic Binding, Single & Double Dispatch

This post is a term explanation for dispatch in object-oriented programming – including exam questions and tags.

In a Nutshell

Dispatch refers to the selection of the actual method to be executed for a call. Depending on the language and construct, binding occurs statically at compile time or dynamically at runtime, forming the basis for polymorphism.

Compact Technical Description

Dispatch refers to the resolution of a method call to a concrete implementation. In static dispatch (overloading), the compiler decides based on static types. In dynamic dispatch (overriding), the runtime environment decides based on the actual object type, often via a vtable.

Dispatch variants:

  • Single Dispatch: Selection based on the receiver object
  • Double Dispatch: Selection based on two runtime types (Visitor Pattern)
  • Multiple Dispatch: Selection based on multiple runtime arguments

Dynamic binding enables polymorphism and the Open Closed Principle, but requires correct contracts according to the Liskov Substitution Principle. Static dispatch offers predictability and performance, dynamic dispatch offers flexibility and extensibility.

Exam-Relevant Key Points

  • Static Dispatch: Overloading, compile-time decision
  • Dynamic Dispatch: Overriding, runtime decision
  • vtable: Dispatch table for polymorphic calls
  • Single Dispatch: Only receiver type decides
  • Double Dispatch: Receiver and parameter decide
  • Visitor Pattern: Implements double dispatch
  • Performance: Static dispatch faster than dynamic
  • IHK-relevant: Distinction between overloading vs overriding

Core Components

  1. Virtual Method Table (vtable): Dispatch table for polymorphic methods
  2. Single Dispatch: Standard OOP dispatch mechanism
  3. Double Dispatch: Visitor pattern for complex type relationships
  4. Method Overriding: Dynamic binding in inheritance
  5. Method Overloading: Static binding at compile time
  6. Runtime Type Information (RTTI): Type information at runtime
  7. Dynamic Binding: Resolution at runtime
  8. Static Binding: Resolution at compile time

Practical Examples

Single Dispatch (Standard OOP)

// Single Dispatch - only the receiver type decides
abstract class Tier {
    abstract void machGeraeusch();
}

class Hund extends Tier {
    @Override
    void machGeraeusch() {
        System.out.println("Wuff!");
    }
}

class Katze extends Tier {
    @Override
    void machGeraeusch() {
        System.out.println("Miau!");
    }
}

// Dynamic binding at runtime
Tier tier = new Hund(); // Static type: Tier, Dynamic type: Hund
tier.machGeraeusch(); // Output: "Wuff!" (Single Dispatch)

Double Dispatch with Visitor Pattern

// Double Dispatch - receiver and parameter decide
interface Tier {
    void akzeptiere(Besucher besucher);
}

class Hund implements Tier {
    @Override
    public void akzeptiere(Besucher besucher) {
        besucher.besuche(this); // Double Dispatch
    }
}

class Katze implements Tier {
    @Override
    public void akzeptiere(Besucher besucher) {
        besucher.besuche(this); // Double Dispatch
    }
}

interface Besucher {
    void besuche(Hund hund);
    void besuche(Katze katze);
}

class Tierarzt implements Besucher {
    @Override
    public void besuche(Hund hund) {
        System.out.println("Untersuche Hund: Impfung geben");
    }
    
    @Override
    public void besuche(Katze katze) {
        System.out.println("Untersuche Katze: Krallen schneiden");
    }
}

// Usage
Tier[] tiere = {new Hund(), new Katze()};
Besucher tierarzt = new Tierarzt();

for (Tier tier : tiere) {
    tier.akzeptiere(tierarzt); // Double Dispatch
}
// Output:
// Untersuche Hund: Impfung geben
// Untersuche Katze: Krallen schneiden

Static vs Dynamic Dispatch

class Rechner {
    // Static Dispatch (Overloading)
    public int addiere(int a, int b) {
        return a + b;
    }
    
    public double addiere(double a, double b) {
        return a + b;
    }
}

class PolymorpherRechner {
    // Dynamic Dispatch (Overriding)
    public virtual int berechne(int a, int b) {
        return a + b;
    }
}

class Multiplizierer extends PolymorpherRechner {
    @Override
    public int berechne(int a, int b) {
        return a * b;
    }
}

// Static Dispatch at compile time
Rechner rechner = new Rechner();
int ergebnis1 = rechner.addiere(1, 2); // Compile: addiere(int, int)

// Dynamic Dispatch at runtime
PolymorpherRechner poly = new Multiplizierer();
int ergebnis2 = poly.berechne(3, 4); // Runtime: Multiplizierer.berechne()

Advantages and Disadvantages

Advantages of Dynamic Dispatch

  • Flexibility: Runtime polymorphism enables extensible systems
  • Maintainability: Add new types without code changes
  • Abstraction: Unified treatment of different types
  • Open Closed Principle: Extensible without modification

Disadvantages

  • Performance: Runtime overhead from vtable lookup
  • Complexity: Harder to understand and debug
  • Memory: Additional vtable structures
  • Error-proneness: Runtime errors instead of compile-time errors

Dispatch Mechanisms in Different Languages

Java

// Standard: Single dispatch with vtable
// Double dispatch via Visitor Pattern
interface Shape {
    double area();
    void accept(Visitor visitor);
}

C++

// Direct Support: Multiple Dispatch
#include <boost/variant.hpp>
struct DoubleDispatcher {
    void collide(Asteroid& a, Spaceship& s) { /* ... */ }
    void collide(Spaceship& s, Asteroid& a) { /* ... */ }
};

Python

# Duck Typing: Dynamic resolution
class Animal:
    def make_sound(self):
        pass

class Dog(Animal):
    def make_sound(self):
        return "Woof!"

# Dynamic binding at runtime
def animal_sound(animal):
    return animal.make_sound()  # Dispatch at runtime

Common Exam Questions

  1. What is the difference between single and double dispatch? Single dispatch considers only the receiver type, double dispatch considers receiver and parameter types.

  2. How does a vtable work? A vtable is an array of function pointers that resolves polymorphic method calls at runtime.

  3. When do you use the Visitor Pattern? When operations must be separated from the data structure and double dispatch is required.

  4. Why is dynamic dispatch slower than static dispatch? Because runtime vtable lookup is required instead of direct method calls at compile time.

Most Important Sources

  1. https://en.wikipedia.org/wiki/Dynamic_dispatch
  2. https://docs.oracle.com/javase/tutorial/java/IandI/polymorphism.html
  3. https://refactoring.guru/design-patterns/visitor
Back to Blog
Share:

Related Posts