EMZETT.
Login

Anonymous Classes (Anonyme Klassen)

Kurz: Eine innere Klasse ohne eigenen Namen, die direkt an der Stelle definiert und sofort instanziiert wird, an der sie gebraucht wird — meist für einmalig genutzte, kurze Implementierungen.

Genauer: Anonyme Klassen sparen den Aufwand, für eine nur einmal benötigte Implementierung eines Interfaces oder einer abstrakten Klasse eine vollständige, separat benannte Klasse anzulegen. In modernen Sprachen werden anonyme Klassen für einfache Fälle zunehmend durch kürzere Lambda-Ausdrücke ersetzt.

Im Detail

Der Gedanke dahinter: Wenn eine Implementierung eines Interfaces oder einer abstrakten Klasse an genau einer einzigen Stelle im Code gebraucht wird und nirgendwo sonst wiederverwendet werden soll, lohnt sich kein eigener, benannter Klassen-Typ dafür — man definiert die Klasse “anonym” direkt an Ort und Stelle, als Ausdruck statt als eigene Deklaration.

In pseudocode-ähnlicher Schreibweise (nah an Java, wo dieses Konzept besonders verbreitet ist):

schaltflaeche.onClick(neue anonyme Klasse implementiert ClickListener {
    methode click() {
        zeige_meldung("Button wurde geklickt")
    }
})

Statt vorher extra eine Klasse MeinClickListener implementiert ClickListener { ... } zu deklarieren und dann eine Instanz davon zu übergeben, wird Definition und Verwendung in einem Schritt zusammengefasst. Das hält den Code an der Aufrufstelle kompakt, wenn die Logik wirklich kurz und einmalig ist.

Der Nachteil zeigt sich, sobald die Implementierung wächst: Eine mehrzeilige, verschachtelte anonyme Klasse mitten in einem Methodenaufruf macht den Code schnell unübersichtlich (“Pyramide der Anonymität”). Als Faustregel gilt deshalb: Bleibt die Implementierung auf wenige Zeilen beschränkt (idealerweise eine einzige Methode mit kurzem Körper), ist ein Lambda-Ausdruck heute meist die lesbarere Wahl — Lambdas wurden in vielen Sprachen genau deshalb eingeführt, um den Boilerplate anonymer Klassen für den häufigsten Anwendungsfall (ein Interface mit genau einer Methode) zu ersetzen. Anonyme Klassen bleiben aber relevant, wenn mehrere Methoden implementiert oder zusätzlicher Zustand (eigene Felder) benötigt werden — das kann ein einzelner Lambda-Ausdruck nicht abbilden.

Zugriff auf die umgebende Umgebung

Eine anonyme Klasse kann auf Variablen aus ihrem umgebenden Gültigkeitsbereich zugreifen — das nennt man einen Closure-ähnlichen Effekt, auch wenn eine anonyme Klasse technisch kein reiner Closure im funktionalen Sinn ist. Einschränkung in vielen Sprachen: die von außen erfasste Variable muss final/unveränderlich sein oder sich wie eine solche verhalten, weil sonst nicht klar wäre, welchen Wert die anonyme Klasse sehen soll, sobald sich die Variable nach der Erstellung ändert:

final schwellenwert = 100
liste.filtereMit(neue anonyme Klasse implementiert Filter {
    methode passt(element) {
        return element.wert > schwellenwert   // Zugriff auf äußere Variable, nur lesend erlaubt
    }
})

Sonderfall: anonyme Klassen zum sofortigen Erweitern

Anonyme Klassen werden nicht nur genutzt, um ein Interface zu implementieren, sondern auch, um eine bestehende Klasse punktuell zu erweitern, ohne dafür eine eigene benannte Unterklasse anzulegen — etwa um für einen einzigen Testfall eine Methode zu überschreiben:

konto = neue anonyme Klasse erweitert Konto {
    // Verhalten für genau diesen einen Test überschreiben
    methode berechneZinsen() { return 0 }
}

Vergleich zu anderen Sprachen

Das Grundprinzip “sofort eine namenlose Instanz mit eigenem Verhalten erzeugen” taucht in ähnlicher Form auch außerhalb klassischer OOP-Sprachen auf: JavaScript kennt anonyme Funktionsausdrücke (function() { ... }) und Objektliterale mit Methoden, C# hat mit anonymen Typen (new { Name = "x" }) ein vergleichbares, aber auf reine Daten beschränktes Konzept. Der gemeinsame Nenner ist immer derselbe: Etwas wird gebraucht, das nur an einer Stelle existiert — warum also einen eigenen, dauerhaften Namen dafür vergeben?

Siehe auch: Inner Classes, Lambda, Interface