Schnittstellen Flashcards
Syntax Schnittstelle
public interface Schnittstelle extends Schnittstelle1, ..., Schnittstellen { Konstantendefinitionen Methodendeklarationen }
Schnittstellendeklaration
Der Modifikator public ist optional. Ohne Angabe von public ist
die Schnittstelle nur im selben Paket sichtbar.
Die Deklaration von Schnittstellen als protected oder private ist
nicht zulässig.
Hierarchie von Schnittstellen
Schnittstellen können von keiner, einer oder mehreren Schnittstellen
abgeleitet werden.
Anders als bei Klassen, die eine Hierarchie mit Object als Wurzel
bilden, gibt es keine oberste Schnittstelle.
Schnittstellen bilden keinen zusammenhängenden Graphen.
Was kann in einer Schnittstelle festgelegt werden?
public abstract Methoden:
Legen Anforderungen fest, die Klassen erfüllen müssen, die diese
Schnittstelle implementieren. Das ist die wesentliche Funktion von
Schnittstellen!
Jede Methode einer Schnittstelle ist public, deshalb kann dieser
Modifikator entfallen. Auch abstract ist optional.
pubic static final Variablen:
Definieren Konstanten der Schnittstelle. Modifikatoren public
static final sind optional, d. h. jede Variable, die in einer
Schnittstelle deklariert wird, ist implizit eine Konstante.
default Methoden:
Legen Anforderungen fest, geben dafür jedoch bereits eine
Standardimplementierung. Haben nicht den Modifikator abstract.
Können in Klassen, die die Schnittstelle implementieren,
überschrieben werden.
static Methoden:
Haben wie statische Methoden von Klassen keinen Bezug zu
Objekten, sondern in diesem Fall zur Schnittstelle, in der sie definiert
sind.
Implementierung einer Schnittstelle
Eine Klasse zeigt durch das Schlüsselwort implements an, dass sie
eine Schnittstelle implementiert.
Dadurch versichert die Klasse, dass sich ihre Objekte so verhalten, wie
es die Schnittstelle fordert.
Eine Klasse kann mehrere Schnittstellen implementieren. Die Namen
der Schnittstellen hinter dem Schlüsselwort implements werden
durch Komma getrennt.
Implementiert eine Klasse eine Schnittstelle, so muss sie entweder
jede darin deklarierte Methode implementieren,
oder die Klasse muss als abstrakt deklariert sein.
Eine Klasse, die eine Schnittstelle implementiert, erbt die darin
enthaltenen Konstantendefinitionen.
Implementiert eine Klasse A eine Schnittstelle, so implementiert wegen
Methodenvererbung jede Unterklasse von A ebenfalls die Schnittstelle.
Schnittstelle als Typ
Schnittstellen können zur Typdeklaration von Variablen und als
Ergebnistyp von Methoden verwendet werden.
Verkaufbares einProdukt;
public void fuegeHinzu(Verkaufbares produkt) {
…
}
Zuweisung an Variable mit Schnittstellentyp
Zuweisungen an Variablen, deren Typ eine Schnittstelle ist,
müssen typverträglich sein.
In einer Zuweisung
v = Ausdruck
bei der der Typ der Variable v eine Schnittstelle S ist, muss der Typ
des Ausdrucks
die Schnittstelle S oder eine von S abgeleitete Schnittstelle sein, oder
eine Klasse sein, die S implementiert.
Zur Laufzeit enthält v Objekte von Klassen, die die Schnittstelle S
implementieren. Auf jeden Wert von v sind die Methoden anwendbar,
die in S festgelegt sind.
Vorteile von Schnittstellen als Typ
Codeänderung, durch die eine Variable einen anderen Wert erhält,
erfordert keine Änderung der Deklaration der Variablen. Beispiel:
private List eineListe;
…
eineListe = new ArrayList<>(); // vor Codeänderung
eineListe = new LinkedList<>(); // nach Codeänderung
Codeänderung von ArrayList zu LinkedList erfordert keine Änderung
des Typs der Variablen eineListe.
Codeänderung, durch die eine Methode ein Objekt einer anderen Klasse
zurückgibt, erfordert
keine Änderung im Kopf der Methode,
keine Änderung an Stellen, an denen die Methode aufgerufen wird.
Beispiel:
public Collection gibFahrzeuge() {
ArrayList fahrzeuge; // vor Codeänderung
Set fahrzeuge; // nach Codeänderung
…
return fahrzeuge;
}
Codeänderung von ArrayList zu Set erfordert keine Änderung an den Stellen, an denen gibFahrzeuge aufgerufen wird.
Einer Methode, deren Parameter Schnittstellentypen besitzen, können
beim Aufruf nicht nur spezielle, sondern viele verschiedene Objekte
übergeben werden (das heißt jedoch nicht: beliebige Objekte). Beispiele:
Dieser Methode können nur Objekte der Klasse ArrayList
übergeben werden.
public void fuegeFahrzeugeHinzu(ArrayList)
Dieser Methode können Objekte aller Klassen übergeben werden, die
Collection implementieren, z. B. ArrayList, LinkedList,
TreeSet.
public void fuegeFahrzeugeHinzu(Collection)
Schnittstelle Comparable
Die Schnittstelle Comparable definiert Anforderungen hinsichtlich der
Vergleichbarkeit von Objekten.
Vergleichbarkeit wird z. B. für eine allgemeine Methode zum Sortieren
von Listen benötigt.
Die Schnittstelle Comparable enthält genau eine Methode:
int compareTo(T)
Die allgemeine Sortiermethode ist in der Klasse Collections
implementiert:
public static >
void sort(List list)
sort kann zur Sortierung aller Listen verwendet werden, sofern die
Elemente der Listen die Schnittstelle Comparable implementieren.
compareTo und equals
compareTo und equals müssen so aufeinander abgestimmt sein, dass
gilt:
obj1.compareTo(obj2) = 0 ⇔ obj1.equals(obj2)
Schnittstelle Comparator
Die Methode compareTo der Schnittstelle Comparable wird
verwendet, um die „natürliche Ordnung“ (engl. natural ordering) von
Objekten zu definieren.
Möchte man Objekte nach anderen Kriterien sortieren (z. B. Bücher
anhand ihres Preises), so bietet sich die Schnittstelle Comparator an.
Die Schnittstelle Comparator definiert die Methode
int compare(T, T)}
Ein Objekt der Schnittstelle Comparator (genauer: einer Klasse,
die diese Schnittstelle implementiert) kann durch die Methode
compare zwei Objekte des Typs T miteinander vergleichen.
Comparator als Ordnungsrelation
Verwendet man einen Comparator als Parameter, so kann man eine
Ordnungsrelation an eine Methode übergeben.
In der Klasse Collections ist folgende Methode implementiert:
public static void sort(List, Comparator super T>)
Sie sortiert eine Liste nach beliebigen Sortierkriterien. Bei Aufruf wird
das konkrete Kriterium als Comparator übergeben.
Da ein Comparator lediglich ein Sortierkriterium repräsentiert, ist die
Realisierung einer separaten Klasse mit vernünftigem Namen meist
unnötig kompliziert.
Java ermöglicht elegantere Lösung.
Definition einer Klasse innerhalb einer Klasse
Definition einer anonymen Klasse
Definition eines Lambda-Ausdrucks (Java 8)
Beispielklasse CompareTest (Code-Beispiel Katalog7)
Funktionale Schnittstelle
Eine Funktionale Schnittstelle ist eine Schnittstelle, die genau eine
abstrakte Methode enthält (wie z.B. Comparator) und mit
@FunctionalInterface annotiert ist.
Eine Klasse erfüllt die Anforderungen einer Funktionalen Schnittstelle,
wenn sie genau diese eine Methode definiert. Es geht also bei einer
Funktionalen Schnittstelle genau genommen um eine Funktion!
Anstelle einer (benannten oder anonymen) Klasse kann dort, wo eine
Funktionale Schnittstelle erwartet wird, die entsprechende Funktion
durch einen Lambda-Ausdruck angegeben werden.
Lambda-Ausdrücke
Lambda-Ausdrücke beschreiben konzeptionell eine Funktion. (In Java
werden sie technisch auf innere Klassen abgebildet.)
Collections.sort(buecher,
(Buch b1, Buch b2)
-> (int) Math.signum(b1.gibPreis() - b2.gibPreis()));
Mock-Klassen
Hier bietet sich wieder eine Technik an, die schon im Zusammenhang mit
abstrakten Klassen angewandt wurde: Mock-Klassen.
Zum Test der Methode liesDaten verwendet man eine Attrappe
eines Artikelverarbeiters.
Die Attrappe kann optimal auf den Test abgestimmt werden.
Die Klasse MockArtikelverarbeiter kann in verarbeiteArtikel
die übergebenen Artikel protokollieren (textuell oder besser als Liste
der übergebenen Artikel).
Der Soll/Ist-Vergleich geschieht anhand der Liste von Artikeln, die der
MockArtikelverarbeiter angesammelt hat, und einer
vorgegebenen Artikelliste.