Fachkonzept - Interface
Mehrere Obertypen
Es gibt Situationen, in denen man mehr als einen Obertyp für eine Klasse definieren möchte. Dies kann man durch Vererbungshierarchien erreichen:
Es gibt aber auch Fälle, in denen man gerne zwei Oberklassen definieren würde:
Probleme gibt es, wenn beide Oberklassen gleichnamige Methoden bereitstellen, da dann geklärt sein muss, welche Methode ausgeführt wird (siehe auch Diamond-Problem bei Wikipedia). Um diese Probleme zu vermeiden, ist Mehrfachvererbung in einigen Sprachen - wie z.B. auch in Java - verboten.
Wenn man fordert, dass die vererbten Methoden alle abstrakt sein müssen, können sich die oben genannten Probleme nicht ergeben. Deshalb gibt es in Java und einigen anderen Sprachen das Konzept von Interfaces. Ein Interface kann man sich als rein abstrakte Klasse vorstellen, die nur Methoden definiert, aber keine Methode implementiert. Es wird also nur die Schnittstelle festgelegt, über die man auf ein Objekt des Typs zugreifen kann.
UML-Darstellung
Das Buch-Beispiel von oben lässt sich z.B. mit Hilfe von zwei Interfaces modellieren:
Zusätzlich zu beliebig vielen Interfaces darf eine Klasse eine Oberklasse haben:
Ob man einen Obertyp als Interface oder als Klasse entwerfen sollte, ist nicht immer eindeutig. Als grobe Faustregel könnte man sagen: Wenn ein Verhalten definiert werden soll, das von recht unterschiedlichen Klassen implementiert werden soll, dann könnte ein Interface geschickt sein. Wenn eine konkrete Implementierung mehrfach genutzt werden kann, dann könnten (abstrakte) Klassen geschickter sein.
Java-Syntax
Da alle Methoden eines Interfaces abstrakt sein müssen, muss dies nicht explizit angegeben werden.
Das Interface Druckbar
wird damit folgendermaßen definiert:
public interface Druckbar
{
void drucken();
}
Die Klasse Buch
muss dann die konkrete Implementierung aller Methoden aus
Druckbar
und Wertvoll
liefern.
Man sagt auch: Buch
implementiert Druckbar
und Wertvoll
:
public class Buch extends Gegenstand implements Druckbar, Wertvoll
{
public void drucken() {
// ... tu was getan werden muss ...
}
public int getWert() {
// ... tu was getan werden muss ...
}
}