» Tutorial / Java Grundlagen / Interfaces

Bei Interfaces, oft auch direkt als Schnittstellen bezeichnet, handelt es sich um eine Abart der abstrakten Klassendeklaration. Sie enthält neben diversen Datenelementen lediglich abstrakte Methoden. Auch werden sie für die Mehrfachvererbung eingesetzt, denn Klassen können beliebig viele dieser Schnittstellen implementieren.


» Verwendung nach oben «

Interfaces kommen dort zum Einsatz, wo die Klassen an ihre Grenzen stoßen. Genau wie abstrakte Klassen, so können auch Interfaces Variablen und Methoden vordeklarieren. Des weiteren können Klassen beliebig viele Interfaces implementieren. Klassen sind in so fern eingeschränkt, als dass sie nur eine Basisklasse in einer Vererbungshierarchie haben dürfen. Um dieses Problem nun zu umgehen, kann man in Schnittstellendefinitionen die zu implementierenden Methoden und Datenelemente bestimmen.

Vererbung von mehreren Interfaces

Implementiert eine Klasse ein Interface, so muss sie alle Methoden des Interface überschreiben, da diese implizit als abstrakt deklariert werden.


» Definition eines Interface nach oben «

Nun wollen wir unser erstes Interface schreiben. Syntaktisch nutzen wir das Interface - Schlüsselwort. Der rest ist äquivalent zur Definition einer Klasse. Innerhalb der Definition dürfen lediglich Methodendeklarationen ohne einen Anweisungsrumpf auftreten. Variablen hingegen sind gestattet, müssen allerdings ebenfalls initialisiert werden, da sie implizit als kontant gelten. Außerdem müssen alle Elemente eines Interface als Public deklariert sein.


[Modifikator] interface Interface
{
     [final] [Modifikator] Typ Variable = Wert;
  [abstract] [Modifikator] Typ Methode();
}
    

Das folge Beispiel definiert eine entsprechende Variable und eine abstrakte Methode, die wir hier aber noch nicht implementieren können.


interface MyInterface
{
  public int i = 0;
  public void print();
}    
    

» Implementierung nach oben «

Nachdem wir unser Interface programmiert haben, wollen wir es in einer Vererbungshierarchie implementieren. Syntaktisch kann dies durchaus in Verbindung mit der Ableitung einer anderen Klasse erfolgen. Die Kennzeichnung für die Implementierung eines Interfaces erfolgt über das Implements - Schlüsselwort. Möchte man mehrere Schnittstellen auf einmal übernehmen, so können diese durch ein Komma getrennt notiert werden.


[Modifikator] class Klasse
[extends Superklasse]
implements Interface
{
  // Anweisungen
}
    

Im folgenden Beispiel definieren wir eine Klasse, welche ein Interface implementiert. Beachten Sie, dass die Klasse alle Methoden des Interfaces überschreiben muss. Die Signatur muss dabei exakt mit der Basismethode übereinstimmen.


interface MyInterface
{	
  public String s = "ProgrammersBase.NET";
  public void print();
}
class MyClass implements MyInterface
{
  public void print()
  {
    System.out.print(s);	
  }
}

public class MyTest
{
  public static void main(String[] args)
  {  	
    MyClass object = new MyClass();
    object.print();
  }
}    
    

ProgrammersBase.NET   
    

Wie wir sehen, so vererbt das Interface alle Datenelemente an die neue Klasse und sorgt dafür, dass die entsprechenden Methoden der Schnittstelle überschrieben werden.

Ein weiteres Beispiel soll sowohl die Implementierung mehrerer Schnittstellen demonstrieren, als auch deren gemeinsame Verwendung bei der Ableitung einer Klassenhierarchie. Die Subklasse kann dabei nur eine Basisklasse, aber mehrere Interfaces haben.


interface MyInterface1
{	
  public void print1();
}
interface MyInterface2
{	
  public void print2();
}

class MySuperClass
{		
  protected String s = "ProgrammersBase.NET";
}

class MySubClass extends MySuperClass
implements MyInterface1, MyInterface2
{
  public void print1()
  {
    System.out.println(s);
  }
  public void print2()
  {
    System.out.println("ProgrammersBase.DE");
  }
}

public class MyClass
{
  public static void main(String[] args)
  {  	
    MySubClass object = new MySubClass();
    
    object.print1();
    object.print2();
  }
}
    

ProgrammersBase.NET
ProgrammersBase.DE   
    

» Vererbung von Interfaces nach oben «

Die Verwendung von Interfaces in einer Klassenhierarchie hat einen sehr interessanten Nebeneffekt. Wenn eine beliebige Superklasse ein Interface implementiert und somit alle Datenelemente und Methoden erbt, so wird diese Implementierung auch an alle Subklassen dieser Vaterklasse weitergegeben. Ein einmal implementiertes Interface kommt also auch allen Subklassen zu gute.

Das folgende Beispiel ist an unsere vorhergehende Demonstration angelehnt. Hierbei implementiert bereits die Superklasse das Interface. Die Subklasse erbt alle Elemente und bei der Instanziierung dieser ist es uns gestattet, die entsprechend vererbte Methode aufzurufen.


interface MyInterface
{	
  public void print();
}

class MySuperClass
implements MyInterface
{		
  protected String s = "ProgrammersBase.NET";
	
  public void print()
  {
    System.out.println(s);
  }
}

class MySubClass 
extends MySuperClass
{
	
}

public class MyClass
{
  public static void main(String[] args)
  {  	
    MySubClass object = new MySubClass();
    object.print();
  }
}
    

ProgrammersBase.NET
    

Sofern es gewünscht ist, können die von der Superklasse implementierten Methoden in der Subklasse erneut überschrieben werden.


» Ableiten von Interfaces nach oben «

Auch Interfaces können eine Vererbungshierarchie bilden und voneinander abgeleitet werden. Dabei erbt die Subschnittstelle alle Deklarationen der Basisschnittstelle. Implementiert nun eine Klasse diese Subschnittstelle, so muss sie natürlich auch alle Methoden der Basisschnittstelle überschreiben.

Die Syntax für eine Schnittstellenableitung ist mit der Ableitung von Klassen nahezu identisch.


[Modifikator] interface Interface
extends SuperInterface
{
  // Anweisungen
}
    

Anstatt eine Klasse zwei verschiedene Interfaces implementieren zu lassen, können wir diese auch in einer logischen Hierarchie ableiten und in einem Subinterface zusammenfassen.


interface MyInterface1
{	
  public void print1();
}
interface MyInterface2 extends MyInterface1
{	
  public void print2();
}

class MySuperClass
{		
  protected String s = "ProgrammersBase.NET";
}

class MySubClass extends MySuperClass
implements MyInterface2
{
  public void print1()
  {
    System.out.println(s);
  }
  public void print2()
  {
    System.out.println("ProgrammersBase.DE");
  }
}

public class MyClass
{
  public static void main(String[] args)
  {  	
    MySubClass object = new MySubClass();
    
    object.print1();
    object.print2();
  }
}
    

ProgrammersBase.NET
ProgrammersBase.DE
    

» statische Datenelemente nach oben «

Alle Datenelemente eines Interface sind von vornherein öffentlich und konstant. Daher können die entsprechenden Modifikatoren als optional betrachtet werden. Ansonsten können die Elemente noch statisch deklariert sein, um in den Klassen, in denen die Schnittstelle implementiert wird, einen globalen Gültigkeitsbereich zu erlangen.


[public] [final] static Typ Variable = Wert;
    

» Instanceof nach oben «

Wie wir es im vorangegangenen Kapitel gesehen haben, so läßt sich der Instanceof - Operator auch für Schnittstellen verwenden. Mit diesem kann geprüft werden, ob ein Objekt, beziehungsweise eine Klasse, ein bestimmtes Interface implementiert. Dabei erwartet der binäre Operator ein Objekt und den Typ des Interfaces. Implementiert das Objekt das Interface, so liefert er True zurück.

Operator Typisierung
   
instanceofR,R

Das folgende Beispiel wird das verdeutlichen.


interface MyInterface
{}

class MySuperClass
implements MyInterface
{}

public class MyClass
{
  public static void main(String[] args)
  {  	
    MySuperClass object = new MySuperClass();
    System.out.print(object instanceof MyInterface);
  }
}
    

true
    

« Kapitel Kapitelübersicht nach oben Kapitel »