Abstrakte Klassen
An unserer bisherigen Implementierung der ClosableFrame Klasse ist zu kritisieren, dass wir doch eine ganze Menge Schreibarbeit hatten, um eine Zeile Code (System.exit(0)) zur Ausführung zu bringen. Tatsächlich hätten wir es uns auch einfacher machen können - es gibt nämlich bereits eine Implementierung von WindowListener, „java.awt.event.WindowAdapter“. Die Klasse stellt für alle deklarierten Methoden von WindowListener einen leeren Methodenrumpf bereit, ganz ähnlich wie wir es in „ExitVMWindowListener.java“ mit den ersten sechs Methoden gemacht haben.
Adapter ist ein in diesem Zusammenhang häufig verwendeter Begriff. Klassen, die ein Interface ohne vollständige Funktionalität implementieren, werden meist als Adapterklassen bezeichnet. Sie dienen der Bequemlichkeit: Statt das Interface in einer konkreten Klasse vollständig zu implementieren, leitet man einfach von der Adapterklasse ab und überschreibt die Methode(n), auf die es einem ankommt. (Weitere Beispiele: „java.awt.event.MouseAdapter“ imlementiert java.awt.event.MouseListener, „java.awt.event.KeyAdapter“ implementiert java.awt.event.KeyListener und aus anderem Zusammenhang „org.xml.sax.helpers.XMLReaderAdapter“.
Der Versuch, ein Window Adapter-Objekt mit:
new WindowAdapter(); // funktioniert nicht!
zu erzeugen schlägt allerdings fehlt. Der Compiler mäkelt, dass sich von abstrakten Klassen keine Objekte erzeugen lassen, und damit hat er recht. Wie wird eine Klasse abstrakt? Durch das Schlüsselwort abstract:
public abstract class WindowAdapter { [..]
Warum macht man so etwas? Weil man nicht möchte, dass von einer Klasse Instanzen (Objekte) erzeugt werden. Dafür kann es verschiedene Gründe geben:
- Die Klasse macht nichts sinnvolles wie in unserem Fall. Ein WindowAdapter – Objekt wäre völlig überflüssig, weil alle Methoden leere Rümpfe besitzen. Abstract heißt hier also: Achtung, ich kann nichts, es ist nicht sinnvoll, mich zu instanzieren.
- Die Klasse besitzt nur statische Methoden. Statische Methoden werden durch das Schlüsselwort static gekennzeichnet (public static void main(String[] args) { [..]). Es sind sogenannte „Klassenmethoden“, die aufgerufen werden können, ohne dass eine Instanz der Klasse existiert. Richtig ist der Aufruf von statischen Methoden direkt mit dem Klassennamen, also zum Beispiel: „ClosableFrame.main(new String[]{});“. Statische Methoden lassen sich auch bei abstrakten Klassen benutzen.
- Die Klasse besitzt abstrakte Methoden. Abstrakte Methoden werden wie Methoden in einem Interface geschrieben und durch das Schlüsselwort „abstract“ gekennzeichnet (private abstract double berechne(..);). Sie werden häufig verwendet, um in mehreren abgeleiteten Klassen ggf. unterschiedlich implementiert zu werden. Der Fall ist vergleichbar mit 1., nur dass wir hier einen sehr deutlichen Hinweis bekommen, welche Methode in der abgeleiteten Klasse zu implementieren ist.
Insgesamt sind abstrakte Klassen nicht schwer zu handhaben, da der Compiler schon dafür sorgt, dass mit ihnen nichts schiefgehen kann. Wenn wir also WindowAdapter benutzen wollen, müssen wir eine eigene Klasse davon ableiten und die Methoden, die wir brauchen, überschreiben.