Interface (Java): Unterschied zwischen den Versionen

Aus Byte-Welt Wiki
Zur Navigation springenZur Suche springen
K
K
Zeile 6: Zeile 6:
 
== Basis ==
 
== Basis ==
 
Der Syntax eines Interfaces ähnelt einer Klasse:
 
Der Syntax eines Interfaces ähnelt einer Klasse:
<code=java>[public | protected | private] interface (Name){
+
<syntaxhighlight lang="java">[public | protected | private] interface (Name){
 
   public void methodeA();
 
   public void methodeA();
  
Zeile 14: Zeile 14:
  
 
   public static final int KONSTANTE_A = 3;
 
   public static final int KONSTANTE_A = 3;
}</code=java>
+
}</syntaxhighlight>
 
* Kopf
 
* Kopf
 
** Mit einem [[Modifier_(Java)|Modifier]] wird die Sichtbarkeit des Interfaces geregelt.
 
** Mit einem [[Modifier_(Java)|Modifier]] wird die Sichtbarkeit des Interfaces geregelt.
Zeile 27: Zeile 27:
 
== Vererbung ==
 
== Vererbung ==
 
Ein Interface kann von beliebig vielen anderen Interfaces erben. Dabei wird das Schlüsselwort ''extends'' eingesetzt:
 
Ein Interface kann von beliebig vielen anderen Interfaces erben. Dabei wird das Schlüsselwort ''extends'' eingesetzt:
<code=java>public interface Child extends Mother, Father{
+
<syntaxhighlight lang="java">public interface Child extends Mother, Father{
 
   ...
 
   ...
}</code=java>
+
}</syntaxhighlight>
 
Das Kind-Interface definiert damit alle Methoden und Konstanten, welche schon in den Elter-Interfaces definiert waren. Die Vererbung erlaubt es auch, überall dort das Kind-Interface einzusetzen, wo nur ein Elter-Interface erwartet und benötigt wird.
 
Das Kind-Interface definiert damit alle Methoden und Konstanten, welche schon in den Elter-Interfaces definiert waren. Die Vererbung erlaubt es auch, überall dort das Kind-Interface einzusetzen, wo nur ein Elter-Interface erwartet und benötigt wird.
  
Zeile 36: Zeile 36:
  
 
Ist zum Beispiel folgendes Interface gegeben...
 
Ist zum Beispiel folgendes Interface gegeben...
<code=java>public interface Something{
+
<syntaxhighlight lang="java">public interface Something{
 
   public String doSomething( String somewhat );
 
   public String doSomething( String somewhat );
}</code=java>
+
}</syntaxhighlight>
 
... kann es in einer Methode folgendermassen verwendet werden:
 
... kann es in einer Methode folgendermassen verwendet werden:
<code=java>public String callSomething( Something something ){
+
<syntaxhighlight lang="java">public String callSomething( Something something ){
 
   return something.doSomething( "abc" );
 
   return something.doSomething( "abc" );
}</code=java>
+
}</syntaxhighlight>
  
 
== Interfaces implementieren ==
 
== Interfaces implementieren ==
Zeile 50: Zeile 50:
  
 
Es ist möglich, dass eine Klasse mehr als ein Interface implementiert. In diesem Fall werden die Interfaces durch Kommas getrennt angegeben:
 
Es ist möglich, dass eine Klasse mehr als ein Interface implementiert. In diesem Fall werden die Interfaces durch Kommas getrennt angegeben:
<code=java>public class Klasse implements InterfaceA, InterfaceB{
+
<syntaxhighlight lang="java">public class Klasse implements InterfaceA, InterfaceB{
 
   ...
 
   ...
}</code=java>
+
}</syntaxhighlight>
  
 
== Beispiel ==
 
== Beispiel ==
Zeile 59: Zeile 59:
  
 
Ein Interface ''Haustier'' beschreibt das unbekannte Wesen.
 
Ein Interface ''Haustier'' beschreibt das unbekannte Wesen.
<code=java>public interface Haustier{
+
<syntaxhighlight lang="java">public interface Haustier{
 
   // setzt den Besitzer dieses Haustiers
 
   // setzt den Besitzer dieses Haustiers
 
   public void setBesitzer( String besitzer );
 
   public void setBesitzer( String besitzer );
Zeile 65: Zeile 65:
 
   // Das typische Geräusch, das dieses Haustier macht
 
   // Das typische Geräusch, das dieses Haustier macht
 
   public String laut();
 
   public String laut();
}</code=java>
+
}</syntaxhighlight>
  
 
Ein typischer Vertreter der ''Haustiere'' ist eine ''Katze''.
 
Ein typischer Vertreter der ''Haustiere'' ist eine ''Katze''.
<code=java>public class Katze implements Haustier{
+
<syntaxhighlight lang="java">public class Katze implements Haustier{
 
   public void setBesitzer( String besitzer ){
 
   public void setBesitzer( String besitzer ){
 
     // ignorieren, ich jage lieber Mäuse
 
     // ignorieren, ich jage lieber Mäuse
Zeile 76: Zeile 76:
 
     return "Miau";
 
     return "Miau";
 
   }
 
   }
}</code=java>
+
}</syntaxhighlight>
  
 
Ein eher exotisches Haustier ist hingegen der sprechende ''Papagei''.
 
Ein eher exotisches Haustier ist hingegen der sprechende ''Papagei''.
<code=java>public class Papagei implements Haustier{
+
<syntaxhighlight lang="java">public class Papagei implements Haustier{
 
   private String besitzer;
 
   private String besitzer;
  
Zeile 89: Zeile 89:
 
     return "Krächtz, Hallo " + besitzer + ", Krächtz";
 
     return "Krächtz, Hallo " + besitzer + ", Krächtz";
 
   }
 
   }
}</code=java>
+
}</syntaxhighlight>
  
 
Das Abenteuer beginnt. Zuerst wird eine ''Haustier''-Variable initialisiert, dann wird der "dunkle Raum" betreten.
 
Das Abenteuer beginnt. Zuerst wird eine ''Haustier''-Variable initialisiert, dann wird der "dunkle Raum" betreten.
<code=java>public void abenteuer(){
+
<syntaxhighlight lang="java">public void abenteuer(){
 
   Haustier haustier;
 
   Haustier haustier;
 
   if( Math.random() > 0.5 )
 
   if( Math.random() > 0.5 )
Zeile 102: Zeile 102:
 
   dunklerRaum( haustier );
 
   dunklerRaum( haustier );
 
}
 
}
</code=java>
+
</syntaxhighlight>
  
 
Es ist nicht bekannt, welches Haustier noch in dem Raum ist. Das Interface ''Haustier'' gibt aber Zugriff auf alle Informationen, welche für die Darstellung des Raumes notwendig sind.
 
Es ist nicht bekannt, welches Haustier noch in dem Raum ist. Das Interface ''Haustier'' gibt aber Zugriff auf alle Informationen, welche für die Darstellung des Raumes notwendig sind.
<code=java>public void dunklerRaum( Haustier haustier ){
+
<syntaxhighlight lang="java">public void dunklerRaum( Haustier haustier ){
 
   System.out.println( "Du betrittst einen dunklen Raum." );
 
   System.out.println( "Du betrittst einen dunklen Raum." );
 
   System.out.println( "Plötzlich hörst du ein Geräusch:" );
 
   System.out.println( "Plötzlich hörst du ein Geräusch:" );
 
   System.out.println( haustier.laut() );
 
   System.out.println( haustier.laut() );
 
   System.out.println( "Was das wohl ist?" );
 
   System.out.println( "Was das wohl ist?" );
}</code=java>
+
}</syntaxhighlight>
  
 
= Sinn von Interfaces =
 
= Sinn von Interfaces =

Version vom 8. März 2018, 19:50 Uhr

In Java ist ein Interface eine Schnittstelle die zu implementierende Methoden vorgibt.

Ein Interface wird üblicherweise in einer eigenen Java-Datei gespeichert. Wenn das Interface öffentlich (public) ist, muss der Name der Datei dem Namen des Interfaces entsprechen. Wie Klassen können auch Interfaces in Packages eingeteilt werden. Mit Interfaces lassen sich für Klassen, die thematisch nichts gemeinsam haben, Gemeinsamkeiten definieren.

Syntax

Basis

Der Syntax eines Interfaces ähnelt einer Klasse:

[public | protected | private] interface (Name){
  public void methodeA();

  public int methodeB( boolean x );

  public String methodeC( String x, float y );

  public static final int KONSTANTE_A = 3;
}
  • Kopf
    • Mit einem Modifier wird die Sichtbarkeit des Interfaces geregelt.
    • Das Schlüsselwort interface zeigt an, dass nun ein Interface definiert wird.
    • Der Name des Interfaces muss mit einem Buchstaben beginnen, und kann dann mit jedem beliebigen Buchstaben, Ziffer und auch einigen Sonderzeichen erweitert werden.
  • Rumpf
    • Der Rumpf wird durch geschweifte Klammern gebildet
    • Im Rumpf sind Methodenköpfe definiert. Es ist aber nicht erlaubt die Methoden zu implementieren (Methodenrümpfe sind also nicht erlaubt)
    • Jede definierte Methode ist automatisch public und abstract, das Schlüsselwort "public" ist eigentlich redundant, wird aber trotzdem oft ausgeschrieben.
    • Es können auch Konstanten im Rumpf definiert werden. Alle Variablen im Rumpf sind automatisch public, static und final.

Vererbung

Ein Interface kann von beliebig vielen anderen Interfaces erben. Dabei wird das Schlüsselwort extends eingesetzt:

public interface Child extends Mother, Father{
   ...
}

Das Kind-Interface definiert damit alle Methoden und Konstanten, welche schon in den Elter-Interfaces definiert waren. Die Vererbung erlaubt es auch, überall dort das Kind-Interface einzusetzen, wo nur ein Elter-Interface erwartet und benötigt wird.

Interfaces verwenden

Interfaces werden genau gleich wie Klassen verwendet: verschiedene Methoden können jederzeit aufgerufen werden.

Ist zum Beispiel folgendes Interface gegeben...

public interface Something{
  public String doSomething( String somewhat );
}

... kann es in einer Methode folgendermassen verwendet werden:

public String callSomething( Something something ){
  return something.doSomething( "abc" );
}

Interfaces implementieren

Interfaces werden von Klassen implementiert. Das bedeutet, dass eine Klasse von einem Interface "erbt", und zu den vom Interface definierten Methodenköpfen, beliebige Methodenrümpfe angibt.

Eine Klasse, sofern sie nicht abstrakt ist, muss alle definierten Methoden implementieren. Es ist auch nicht möglich die Methodenköpfe abzuändern, da ein möglicher Aufrufer nichts von den abgeänderten Methoden wüsste.

Es ist möglich, dass eine Klasse mehr als ein Interface implementiert. In diesem Fall werden die Interfaces durch Kommas getrennt angegeben:

public class Klasse implements InterfaceA, InterfaceB{
  ...
}

Beispiel

In einem Textadventure betritt der Spieler einen dunklen Raum. In diesem Raum ist ein Haustier, doch es ist nicht bekannt welches. Softwaremässig lässt sich das folgendermassen abbilden:

Ein Interface Haustier beschreibt das unbekannte Wesen.

public interface Haustier{
  // setzt den Besitzer dieses Haustiers
  public void setBesitzer( String besitzer );

  // Das typische Geräusch, das dieses Haustier macht
  public String laut();
}

Ein typischer Vertreter der Haustiere ist eine Katze.

public class Katze implements Haustier{
  public void setBesitzer( String besitzer ){
    // ignorieren, ich jage lieber Mäuse
  }

  public String laut(){
    return "Miau";
  }
}

Ein eher exotisches Haustier ist hingegen der sprechende Papagei.

public class Papagei implements Haustier{
  private String besitzer;

  public void setBesitzer( String besitzer ){
    this.besitzer = besitzer;
  }

  public String laut(){
    return "Krächtz, Hallo " + besitzer + ", Krächtz";
  }
}

Das Abenteuer beginnt. Zuerst wird eine Haustier-Variable initialisiert, dann wird der "dunkle Raum" betreten.

public void abenteuer(){
  Haustier haustier;
  if( Math.random() > 0.5 )
    haustier = new Papagei();
  else
    haustier = new Katze();

  haustier.setBesitzer( "Emma" );
  dunklerRaum( haustier );
}

Es ist nicht bekannt, welches Haustier noch in dem Raum ist. Das Interface Haustier gibt aber Zugriff auf alle Informationen, welche für die Darstellung des Raumes notwendig sind.

public void dunklerRaum( Haustier haustier ){
  System.out.println( "Du betrittst einen dunklen Raum." );
  System.out.println( "Plötzlich hörst du ein Geräusch:" );
  System.out.println( haustier.laut() );
  System.out.println( "Was das wohl ist?" );
}

Sinn von Interfaces

Interfaces sind ein wichtiges Konzept von Java, aber wofür kann man sie einsetzen?

Module

Module können unterschiedlichste Dinge sein. Einzelne Klassen können Module sein, eine Gruppe von Klassen (wie z.B. Swing) kann ein Modul sein, ganze Programme oder Libraries sind Module. Module können sogar verschachtelt sein. Eines ist aber allen Modulen gemeinsam: sie sind abgeschlossene, komplette Systeme mit einer klar definierten Funktion. Man weiss nicht, wie sie intern funktionieren, aber man kennt ihre Schnittstellen, und kann so mit ihnen arbeiten.

Die deutsche Übersetzung von "Interface" ist "Schnittstelle". Interfaces eignen sich um verschiedene Module zu verbinden. Die vom Modul definierten Interfaces werden vom Benutzer implementiert, so sprechen Benutzer und Modul dieselbe "Sprache", und können interagieren.

Ein Beispiel: das Modul JTable benutzt das Interface TableModel um die Daten, die es zeichnen wird, zu finden. Dem Model JTable ist es egal, wie die Daten gespeichert werden, es ist nur daran interessiert, dass es auf die Daten zugreiffen kann.

Abstraktion

Interfaces helfen auch dabei, nur die wesentlichen Dinge zu betrachten. Man kann für jeden Algorithmus eines oder mehrere Interfaces beschreiben, die genau die Methoden enthalten, welche unbedingt benötigt werden. Ein Beispiel ist ein Sortieralgorithmus: er muss nur wissen, wie man zwei Objekte vergleicht, und wie das grössere Objekt bestimmt werden kann. Entsprechend wird ein Interface Comparator definiert, welches genau dies macht. Dieses Comparator-Interface kann nun für unterschiedlichste Objekttypen implementiert werden. Ein Comparator vergleicht Dateien anhand ihrer Grösse, ein anderer vergleicht Bildschirme anhand ihrer Auflösung. Dem Sortieralgorithmus bleiben diese Details verborgen, er kann sich auf seine Hauptaufgabe, das Sortieren, konzentrieren.