9.2.7 | Anonyme Klasse |
Für die Reaktion auf Ereignisse werden in Verbindung mit dem Delegationsmodell in der Praxis sehr häufig anonyme Klassen eingesetzt (siehe auch Abschnitt 4.13.6). Der Vorteil des Delegationsmodells liegt darin, dass die Reaktion des Ereignisses nach Möglichkeit vom Ereignisfluss entkoppelt wird. Jedoch muss bei jeder Reaktion auf ein Ereignis ein EventListener-Interface implementiert werden. Die Implementierung kann entweder direkt in der Klasse erfolgen, in der das Ereignis ausgelöst wird, oder es wird eine neue Klasse definiert, die das Listener-Interface implementiert, die Ereignisse abfängt und verarbeitet. Das ist oftmals für den Programmierer recht umständlich. Doch genau hierfür können anonyme Klassen sehr gut eingesetzt werden, wie folgendes Beispiel demonstriert:... Button b = new Button("submit"); b.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { submit(); } } ... public void submit() { ... } ...Zunächst wird ein neuer Button erzeugt. Bei der Registrierung des ActionListener wird nicht einfach ein bereits vorhandener Verweis übergeben, sondern es wird eine anonyme Klasse erzeugt, die das Interface ActionListener implementiert. In der dort implementierten Methode actionPerformed() kann man nun den Code unterbringen, der beim Eintritt des Ereignisses ausgeführt werden soll. Diese Technik bietet sich vor allem dann an, wenn zur Reaktion auf ein Ereignis vordefinierte Methoden zur Verfügung stehen, wie es im obigen Beispiel der Fall ist (submit() zur Reaktion auf den Buttondruck). Bei der Verwendung der vordefinierten Methoden sollte man jedoch die Zugriffsrechte der anonymen Klasse berücksichtigen. Aus der anonymen Klasse könnte man z. B. keine private-Methode der Wirtsklasse aufrufen.
Auch in Verbindung mit Event-Adaptern können anonyme Klassen sinnvoll eingesetzt werden. Hierzu wird bei der Registrierung des Event-Listener nun keine anonyme Implementierung für das Interface selbst angelegt, sondern eine abgeleitete Klasse eines Event-Adapters. Das Beispiel aus dem letzten Abschnitt hat folgenden Quellcode, wenn es mit anonymen Klassen implementiert wird:import java.applet.Applet; import java.awt.*; import java.awt.event.*; public class AnonymousMouseAdapterDemo extends Applet { public void init() { setBackground(Color.blue); addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent e) { showPoint(e.getX(), e.getY()); } }); } public void showPoint(int x, int y) { getAppletContext().showStatus("click at x:" +x+" y:"+y); } }Wie man unschwer erkennen kann, wurde der Umfang des Quellcodes durch die Verwendung von anonymen Klassen deutlich reduziert. Bei der Registrierung des Event-Listeners wird nun einfach ein MouseAdapter-Exemplar erzeugt, wobei lediglich die Methode mouseClicked() neu definiert wird. Hierdurch macht man sich folgende Vorteile zunutze:
- Für die Definition eines Event-Adapters muss man keine vollständige Klassendefinition schreiben. Dadurch kann man sich viel Schreibarbeit sparen.
- Es werden trotzdem die Vorteile des Event-Adapters genutzt, d. h. muss man ein EventListener-Interface implementieren, in dem mehr als eine Methode definiert ist, genügt es, nur die zu überschreiben, die wirklich benötigt werden.