Guido Krüger - JAVA 1.1 lernen - Kapitel 7

Previous Page Previous Page TOC TOC Index Next Page Previous Page



Interfaces

Es wurde bereits erwähnt, daß es in Java keine Mehrfachvererbung von Klassen gibt. Die möglichen Schwierigkeiten im Umgang mit mehrfacher Vererbung und die Einsicht, daß das Ererben von nichttrivialen Methoden aus mehr als einer Klasse in der Praxis selten zu erreichen ist, haben die Designer dazu veranlaßt, dieses Feature nicht zu realisieren. Andererseits sah man es sehr wohl als wünschenswert an, Methodendeklarationen von mehr als einer Klasse zu erben und hat mit den Interfaces ein Ersatzkonstrukt geschaffen, das genau dieses Feature bietet.

Definition eines Interfaces

Ein Interface ist eine besondere Form einer Klasse, die ausschließlich abstrakte Methoden und Konstanten enthält. Anstelle von class wird zur Definition eines Interfaces das Schlüsselwort interface verwendet. Alle Methoden sind daraufhin standardmäßig abstrakt. Das folgende Listing definiert ein Interface Fortbewegungsmittel, das die Methoden kapazitaet und kilometerPreis definiert:

public interface Fortbewegungsmittel
{
  public int kapazitaet();
  public double kilometerPreis();
}

Verwendung von Interfaces

Was bei der Vererbung von Klassen als Ableitung bezeichnet wird, nennt man bei Interfaces Implementierung. Durch das Implementieren eines Interfaces verpflichtet sich die Klasse, alle Methoden, die im Interface definiert sind, zu implemetieren. Fehlt eine Methode, so gibt es einen Compilerfehler. Die Implementierung eines Interfaces wird durch das Schlüsselwort implements bei der Klassendefinition angezeigt.

Beispiel

Als Beispiel wollen wir die Klasse Auto um das neue Interface Fortbewegungsmittel erweitern und die Methoden kapazitaet und kilometerPreis implementieren:

public class Auto
implements Fortbewegungsmittel
{
  public  String name;
  public  int    erstzulassung;
  public  int    leistung;
  private int    anzahlSitze;
  private double spritVerbrauch;
  private double spritPreis;

  public double kapazitaet()
  {
    return anzahlSitze;
  }

  public double kilometerPreis()
  {
    return spritVerbrauch*spritPreis/100;
  }

}

Ebenso wie die Klasse Auto könnte auch jede andere Klasse das Interface Fortbewegungsmittel implementieren und Konkretisierungen der beiden Methoden vornehmen. Nützlich ist dies insbesondere für Klassen, die in keinem direkten Zusammenhang mit der Klasse Auto und ihrer Vererbungshierarchie stehen. Um ihr gewisse Eigenschaften eines Fortbewegungsmittels zu verleihen, könnte also beispielsweise auch die Klasse Teppich dieses Interface implementieren.

Hinweis

Eine Klasse kann auch dann ein Interface implementieren, wenn sie bereits von einer anderen Klasse abgeleitet ist. In diesem Fall erbt die neue Klasse wie gewohnt alle Eigenschaften der Basisklasse und hat zusätzlich die Aufgabe, die abstrakten Methoden des Interfaces zu implementieren.

Beispiel

Das folgende Interface Sammlerstueck mag bei gewöhnlichen Autos keine Anwendung finden, ist bei einem Oldtimer aber durchaus sinnvoll:

public Interface Sammlerstueck
{
  public double sammlerWert();
  public String bisherigeAusstellungen();
}

public class Oldtimer
extends Auto
implements Sammlerstueck
{
  //...
}

Da ein Sammlerstueck aber durchaus auch in ganz anderen Vererbungshierarchien auftauchen kann als bei Autos (beispielsweise bei Briefmarken, Schmuck oder Telefonkarten), macht es keinen Sinn, diese Methoden in den Ableitungsbäumen all dieser Klassen wiederholt zu deklarieren. Statt dessen sollten die Klassen das Interface Sammlerstueck implementieren und so garantieren, daß die Methoden sammlerWert und bisherigeAusstellungen zur Verfügung stehen.

Implementieren mehrerer Interfaces

Eine Klasse kann nicht nur ein einzelnes, sondern eine beliebige Anzahl an Interfaces implementieren. So ist es beispielsweise problemlos möglich, eine aus Flugzeug abgeleitete Klasse Doppeldecker zu definieren, die sowohl Sammlerstueck als auch Fortbewegungsmittel implementiert:

public class Doppeldecker
extends Flugobjekt
implements Fortbewegungsmittel, Sammlerstueck
{
  //...
}

Die Klasse Doppeldecker muß dann alle in Sammlerobjekt und Fortbewegungsmittel deklarierten Methoden implementieren.

Interfaces sind Klassen

Interfaces besitzen zwei wichtige Eigenschaften, die auch Klassen haben:

Hinweis

Es macht also Sinn, ein Interface als eine Typvereinbarung anzusehen. Eine Klasse, die dieses Interface implementiert, ist dann vom Typ des Interfaces. Wegen der Mehrfachvererbung von Interfaces kann eine Instanzvariable damit insbesondere mehrere Typen haben und zu mehr als einem Typen zuweisungskompatibel sein.

Konstanten in Interfaces

Neben abstrakten Methoden können Interfaces auch Konstanten, also Variablen mit den Attributen static und final, enthalten. Wenn eine Klasse ein solches Interface implementiert, erbt es gleichzeitig auch all seine Konstanten. Es ist auch erlaubt, daß ein Interface ausschließlich Konstanten enthält.

Beispiel

Dieses Feature kann zum Beispiel nützlich sein, wenn ein Programm sehr viele Konstanten definiert. Anstatt diese in ihren korrespondierenden Klassen zu belassen und mit Klasse.Name aufzurufen, könnte ein einzelnes Interface definiert werden, das alle Konstantendefinitionen vereinigt. Wenn nun jede Klasse, die eine der Konstanten benötigt, dieses Interface implementiert, so stehen alle darin definierten Konstanten direkt zur Verfügung und können ohne die Qualifizierung mit einem Klassennamen aufgerufen werden.

Beispiele aus der Java-Klassenbibliothek

Die Java-Klassenbibliothek definiert und implementiert selbst eine ganze Reihe von Interfaces. Drei von ihnen sollen hier kurz vorgestellt werden.

Runnable

Das Interface Runnable wird zur Implementierung von Threads verwendet, und zwar insbesondere dann, wenn die betreffende Klasse selbst nicht direkt aus Thread abgeleitet werden kann. Runnable deklariert lediglich die Methode run, deren Rumpf den ausführbaren Code des Threads enthält. Der Umgang mit Threads wird in Kapitel 10 erklärt.

Enumeration

Das Interface Enumeration wird zur Deklaration von Enumeratoren verwendet. Enumeratoren dienen dazu, alle Elemente von Kollektionen (z.B. Hashtable oder Vector) nacheinander zu durchlaufen. Enumeration definiert die Methoden nextElement und hasMoreElements. Sie dienen dazu, das nächste Element der Kollektion zu holen bzw. zu testen, ob weitere Elemente vorhanden sind.

Cloneable

Dieses Interface ist etwas untypisch, denn es besitzt weder Methoden noch Konstanten. Es dient lediglich dazu, dem Compiler anzuzeigen, daß eine Klasse die Methode clone unterstützt und damit die Fähigkeit besitzt, sich selbst zu kopieren.


Previous Page Previous Page Page Top TOC Index Next Page Previous Page

(C) 1997 Guido Krueger, "Java 1.1 lernen", Addison-Wesley, Bonn, 1997