Implementierung des Interface an die Default-Klasse delegieren in Java

In diesem Beitrag werden wir eine Default-Implementierung eines Interfaces entwickeln und die Funktionalität dieser Default-Implementierung in einer Delegationsklasse wiederverwenden.

Die Idee dabei ist, die Vorteile eines Interfaces (Mehrfachverwendung in unterschiedlichen Klassenhierarchien) mit denen einer Klasse (Teilimplementierung der Methoden, Verwendung von Konstruktoren und statischen Elementen) zu kombinieren.

Dabei stellt ein Interface die Methodendeklarationen zur Verfügung und eine Default-Klasse implementiert diese Methoden als Referenzimplementierung (Default-Implementierung).

plhq_teaser_hbox_gelb_fotolia_RA Studio_46292813

Unser großes
Android Online-Kurs
Gesamtpaket



Weitere Infos

Implementieren des Interfaces mit Hilfe einer Default-Klasse (Default-Implementierung)

Da in einem Interface alle Methoden abstrakt sind, müssen sie von jeder Klasse, die das Interface verwendet, implementiert werden. Um dies zu umgehen, bietet sich eine Default-Implementierung des Interfaces an.

Die Default-Implementierung ist eine Klasse, die das Interface und alle sinnvoll realisierbaren Interface-Methoden implementiert.

Von dieser Default-Klasse können sich andere Klassen ableiten und müssen somit nicht erneut die Interface-Methoden implementieren, sondern erben diese von der Default-Implementierung.

Der folgende Quellcode enthält unser Interface KettenInterface, das die beiden abstrakten Methoden setNachfolger und getNachfolger deklariert:

Beispielanwendung: Das Interface KettenInterface

/*
* Beispielanwendung: das Interface KettenInterface
*/

public interface KettenInterface
{
  // alle Methoden in Interfaces sind implizit public und abstract
  // jede dieser Methoden ist public und abstract
  public abstract void setNachfolger (KettenInterface nf);
  KettenInterface getNachfolger();
}

Unser Interface KettenInterface wird im Folgenden von unserer Default-Klasse DefaultKette implementiert. Da unser Interface nicht sehr komplex ist, hält sich der Programmieraufwand unserer Default-Implementierung in Grenzen.

Der folgende Java-Quelltext enthält die Klasse DefaultKette, in der die Methoden des Interfaces KettenInterface implementiert werden:

Beispielanwendung: Die DefaultKette-Klasse

/*
* Beispielanwendung: die DefaultKette-Klasse implementiert das Interface KettenInterface
*/

public class DefaultKette implements KettenInterface
{
  public String name;
  private KettenInterface nachfolger;

  public DefaultKette (String name, KettenInterface nf)
  {
    this.name = name;
    this.nachfolger = nf;
  }

  public void setNachfolger (KettenInterface nf)
  {
    nachfolger = nf;
  }

  public KettenInterface getNachfolger()
  {
    return nachfolger;
  }
}

Die oben definierte Klasse DefaultKette stellt eine sehr einfache Implementierung des Interfaces dar und ist in dieser Form auch lauffähig. Andere Klassen können sich von der DefaultKette-Klasse ableiten und haben dadurch das Interface KettenInterface automatisch auch implementiert.

Die Default-Implementierung kann auch sehr nützlich für die Dokumentation des Interfaces sein, da sie auch als die Referenzimplementierung für das Interface verwendet werden kann.

Soll unser Interface KettenInterface in einer anderen Klassenhierarchie verwendet werden, ist das Ableiten von der Default-Klasse nicht möglich. Stattdessen bietet es sich an, die Implementierung des Interfaces an die bereits vorhandene Default-Klasse DefaultKette zu delegieren.

Erstellen der Delegations-Klasse und Delegieren der Interfaceimplementierung an die Default-Klasse

Soll nicht von der Default-Klasse abgeleitet aber dennoch das KettenInterface verwendet werden, müssten alle Interface-Methoden nochmals implementiert werden.

Dieser Schritt kann eingespart werden, wenn man die Implementierung des Interfaces an die Default-Implementierung delegiert. Dies verringert den Programmieraufwand und minimiert die Fehleranfälligkeit des geschriebenen Quellcodes.

Um die Implementierung zu delegieren, muss die neue Klasse DelegationsKette eine Membervariable vom Typ des Interfaces KettenInterface erhalten. An diese Objektvariable können dann alle Aufrufe der Interface-Methoden delegiert werden.

Der folgende Java-Quellcode enthält die Klasse DelegationsKette, die mit Hilfe des Objekts defKette das Interface KettenInterface implementiert und zwar mittels Delegation:

Beispielanwendung: Die DelegationsKette-Klasse

/*
* Beispielanwendung: die DelegationsKette-Klasse implementiert das Interface KettenInterface
*/

public class DelegationsKette implements KettenInterface
{
  private KettenInterface defKette = new DefaultKette("Delegationselement", null);

  public void setNachfolger (KettenInterface nf)
  {
    defKette.setNachfolger(nf);
  }

  public KettenInterface getNachfolger()
  {
    return defKette.getNachfolger();
  }
}

Die neue Klasse DelegationsKette definiert zwar die Interface-Methoden, nutzt dazu aber die Funktionalität des Objekts defKette, welches eine Instanz der Default-Klasse DefaultKette ist.

Über das Objekt defKette werden die Methodenaufrufe an die Default-Implementierung weitergeleitet.

Um unseren Java-Quellcode zu testen, benötigen wir noch eine Testklasse. Dazu definieren wir die Klasse DelegationsTest, die in dem unten angegebenen Quelltext definiert wird:

Beispielanwendung: Die Testklasse für das Interface

/*
* Beispielanwendung: die Testklasse für das Interface
*/

public class DelegationsTest
{
  public static void main (String[] args)
  {
    KettenInterface delKette = new DelegationsKette();

    KettenInterface defKette1  = new DefaultKette("Default Element 1", null);
    KettenInterface defKette2  = new DefaultKette("Default Element 2", null);
    
    delKette.setNachfolger(defKette1);
    delKette.getNachfolger().setNachfolger(defKette2);

    System.out.println("\n" + delKette);
    System.out.println("\n" + ((DefaultKette) delKette.getNachfolger()).name);
    System.out.println(((DefaultKette) delKette.getNachfolger().getNachfolger()).name);
  }
}

In der main-Methode unserer Testklasse legen wir zuerst das Objekt delKette vom Typ unseres Interfaces KettenInterface an. Das Objekt ist eine Instanz unserer Delegationsklasse DelegationsKette.

Als nächstes erzeugen wir die beiden Objekte defKette1 und defKette2 vom Typ des Interfaces KettenInterface. Beide Objekte sind Instanzen der Klasse DefaultKette, welche die Referenzimplementierung des Interfaces KettenInterface ist.

Anschließend wird dem Objekt delKette als Nachfolger das Objekt defKette1 mit Hilfe der Interface-Methode setNachfolger zugewiesen. Die Funktionalität, die für diese Zuweisung benötigt wird, erhält das delKette-Objekt von seiner Membervariable defKette in der Klassendefinition DelegationsKette.

Als vierter Schritt wird dem Nachfolger des Objekts delKette als Nachfolger das Objekt defKette2 zugewiesen. Auch diese Aufgabe wird an die Membervariable defKette der Klasse DelegationsKette delegiert.

plhq_teaser_hbox_gelb_fotolia_RA Studio_46292813

Unser großes
Android Online-Kurs
Gesamtpaket



Weitere Infos

Als letzten Schritt werden die Informationen über das Objekt delKette und dessen Nachfolger auf der Kommandozeile ausgegeben. Dabei muss eine Typ-Umwandlung erfolgen, da als Rückgabewert ein Objekt vom Typ des Interface KettenInterface zurückgegeben wird.

Wir wissen, dass das zurückgegebene Objekt eine Instanz der Klasse DefaultKette ist, und können daher den type cast nach DefaultKette durchführen. Dadurch können wir auf die Membervariable name der DefaultKette-Klasse zugreifen.

Die folgende Abbildung enthält die Konsolenausgabe unserer Java-Anwendung:

Java Interface Delegation

Aufgaben an die Default-Implementierung deligieren in Java – Ausgabe der Beispielanwendung

Der folgende Link führt euch zurück zum Java Programmier Kurs.


Comments 1

  1. Pingback: Interfaces (Schnittstellen) in Java

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.