18.8 Klasse - abstrakte Klasse - Interface

Dieses kleine Unterkapitel enthält eine Zusammenstellung über verschiedene Arten von Klassen. Nicht jede Einzelheit kann beim ersten Durchgang des Kurses verstanden werden. Man kehre später immer mal wieder zu diesem kleinen Unterkapitel zurück
 

  Erbt eine Klasse A von einer Klasse B, stehen ihr alle Attribute und Methoden von B zur Verfügung, so als gehörten sie zu A selbst, vorausgesetzt die Attribuite und die Methoden sind in der Klasse  B nicht private sondern public oder protected. Es ist wichtig, dass wir grundsätzlich drei Arten des Vererbens unterscheiden.
 
1. Variante A erbt von einer 'normalen' Klassen B, d.h. alle Methoden, die in B implementiert sind, können so verwendet werden, als wären sie auch in A implementiert. Von A können Instanzen gebildet werden. Dass eine Klasse A von einer solchen 'normalen' Klasse B erben will, teilt sie dem Compiler mit dem  reservierten Wort extends mit.

public class A extends B{
  ...
}

Geerbte Methoden können überschrieben werden. Auf überschriebene Methoden kann man aber immer noch mit super zugreifen.
 

2. Variante A erbt von einer abstrakten Klasse B, sie erbt also von einer Klasse, die mindestens eine abstrakte Methode besitzt. Dabei ist eine Methode abstrakt, wenn ihre Signatur festgelegt ist, aber die Methode keinen Rumpf und damit auch keine Funktionalität besitzen.

z.B. public abstract void <MethodenName>(....);

Von solchen abstrakten Klassen B kann man keine Instanz erzeugen. Von abstrakten Klassen kann man auch erben (extends). Die erbende Klasse A ist auch wieder abstrakt, es sei denn, alle von B geerbten abstrakten Methoden  wird in A implementiert. In diesem Fall kann man von A auf die gewohnte Weise Instanzen bilden.
 

3. Variante  A erbt von einem Interfaces. Dabei ist ein Interface ein Klasse, die nur abstrakte Methoden besitzt. Auch von Ihnen kann man keine Instanzen bilden, es sei denn, man implementiert dabei gleichzeitig die abstrakten Methoden. Statt zu sagen, A erbt vom Interface B, sagen wir lieber A implementiert das Interface B und schreiben anstelle des reservierten Wortes extends dann implements.

Mehrfachvererbung mit extends gibt es nicht. Denn es könnte Konflikte geben, die Sprachen, die Mehrfachvererbung zulassen, mit einer Reihe von Tricks umgehen. Mehrere Interfaces zu implementieren dagegen geht, da diese Konflikte nicht auftreten.

Der Sinn von Interfaces liegt darin, dass man den Programmierer zwingt, bestimmte Methoden mit vorgefertigter Signatur zu implementieren, wie etwa die run()-Methode des Interfaces in Runnable. So kann man, nur wenn run() der Signatur nach richtig implementiert ist, die 'Runnable-Instanz' sinnvoll an einen Konstruktor von Thread übergeben. Man kann also einem Konstruktor von Thread keine beliebe Klasse übergeben, selbst wenn man dort run() vernünftig implementiert hat. Die Zusicherung fehlt eben.

Nun gibt es Interfaces, die mehrerer (abstrakte) Methoden besitzen, wie etwa das Interface MouseMotionListener. Es hat die abstrakten Methoden mouseDragged(MouseEvent e) und MouseMoved(MouseEvent e). Implementiert man nun das Interface MouseMotionListener, so muss man beide abstrakte Methoden implementieren, auch wenn man nur eine der beiden benötigt. Das ist umständlich. Java stellt für MouseMotionListener wie auch für alle Interfaces mit mehr als einer abstrakten Methode sog. Adapterklassen zur Verfügung. So gibt es die Klasse MouseMotionAdapter, die die abstrakten Methoden von MouseMotionListener implementiert. Allerdings haben die so implementierten Methoden keinerlei Funktionalität. Das kann man so sehen: Im Inteface MouseMotionListerner gibt es, wie schon erwähnt, die Methode

public abstract void mousedragged(MouseEvent e);

in der Adapterklasse wird daraus:

public void mousedragged(MouseEvent e){}

Die Methode ist jetzt nicht mehr abstrakt, im Anweisungsblock steht aber nichts, so dass die implementierte Methode keinerlei Funktionalität besitzt: sie kann nichts. Das gleiche macht man nun mit allen anderen abstrakten Klassen des Interfaces. Statt nun das Interfaces MouseMotionListener(MouseEvent e) zu implementieren (implements) und dabei alle geerbten abstrakten Methode zu überschreiben, kann man von MousMotionAdapter erben (extends) und muss nur noch die gewünschte Methode überschreiben. Diese Vereinfachung funktioniert natürlich nur dann, wenn wir nicht noch gleichzeitig von einer anderen Klasse erben wollen.
 

zu 18.9 Übungen
zur Startseite www.pohlig.de  (C) MPohlig 2004