1. Fähigkeiten
Um die Vorteile von Schnittstellen und deren Verwendung besser zu verstehen, müssen wir über einige abstraktere Dinge sprechen.
Eine Klasse modelliert normalerweise ein bestimmtes Objekt. Eine Schnittstelle entspricht weniger Objekten als vielmehr ihren Fähigkeiten oder Rollen.
Dinge wie Autos, Fahrräder, Motorräder und Räder lassen sich beispielsweise am besten als Klassen und Objekte darstellen. Aber ihre Fähigkeiten – wie „Ich kann geritten werden“, „Ich kann Menschen transportieren“, „Ich kann stehen“ – lassen sich besser als Schnittstellen darstellen. Hier sind einige Beispiele:
Code | Beschreibung |
---|---|
|
Entspricht der Fähigkeit, sich zu bewegen |
|
Entspricht der Reitfähigkeit |
|
Entspricht der Fähigkeit, Dinge zu transportieren |
|
Die Wheel Klasse kann umziehen |
|
Die Car Klasse kann sich bewegen, reiten und Sachen transportieren |
|
Die Skateboard Klasse kann sich bewegen und geritten werden |
2. Rollen
Schnittstellen vereinfachen das Leben eines Programmierers erheblich. Sehr oft hat ein Programm Tausende von Objekten, Hunderte von Klassen, aber nur ein paar Dutzend Schnittstellen , also Rollen . Es gibt wenige Rollen, aber es gibt viele Möglichkeiten, sie zu kombinieren (Klassen).
Der springende Punkt ist, dass Sie nicht für jede Klasse Code schreiben müssen, um mit jeder anderen Klasse zu interagieren. Sie müssen lediglich mit ihren Rollen (Schnittstellen) interagieren.
Stellen Sie sich vor, Sie wären ein Haustiertrainer. Jedes der Haustiere, mit denen Sie arbeiten, kann verschiedene Fähigkeiten haben. Sie geraten mit Ihrem Nachbarn in einen freundschaftlichen Streit darüber, wessen Haustiere den meisten Lärm machen können. Um die Sache zu klären, stellen Sie einfach alle Haustiere auf, die „sprechen“ können, und geben ihnen den Befehl: „Sprich!“
Es ist dir egal, was für ein Tier sie sind oder welche anderen Fähigkeiten sie haben. Auch wenn sie einen Dreifachsalto machen können. In diesem besonderen Moment interessiert Sie nur ihre Fähigkeit, laut zu sprechen. So würde es im Code aussehen:
Code | Beschreibung |
---|---|
|
Die CanSpeak Fähigkeit. Diese Schnittstelle versteht den Befehl to speak , was bedeutet, dass sie über eine entsprechende Methode verfügt. |
|
Tiere, die diese Funktion haben.
Um das Verständnis zu erleichtern, haben wir die Klassennamen auf Englisch angegeben. Dies ist in Java erlaubt, aber höchst unerwünscht.
|
|
Und wie geben wir ihnen den Befehl? |
Wenn die Anzahl der Klassen in Ihren Programmen Tausende erreicht, werden Sie ohne Schnittstellen nicht mehr leben können. Anstatt die Interaktion von Tausenden von Klassen zu beschreiben, reicht es aus, die Interaktion von einigen Dutzend Schnittstellen zu beschreiben – das vereinfacht das Leben erheblich.
Und in Kombination mit Polymorphismus ist dieser Ansatz im Allgemeinen ein voller Erfolg.
3. Die default
Implementierung von Schnittstellenmethoden
Abstrakte Klassen können Variablen und Implementierungen von Methoden haben, aber keine Mehrfachvererbung. Schnittstellen können keine Variablen oder Implementierungen von Methoden enthalten, diese können jedoch mehrfach vererbt werden.
Die Situation wird in der folgenden Tabelle ausgedrückt:
Fähigkeit/Eigenschaft | Abstrakte Klassen | Schnittstellen |
---|---|---|
Variablen | ✔ | ✖ |
Methodenimplementierung | ✔ | ✖ |
Mehrfachvererbung | ✖ | ✔ |
Daher wollten einige Programmierer unbedingt, dass Schnittstellen über die Möglichkeit zur Methodenimplementierung verfügen. Die Möglichkeit, eine Methodenimplementierung hinzuzufügen, bedeutet jedoch nicht, dass immer eine hinzugefügt wird. Fügen Sie es hinzu, wenn Sie möchten. Oder wenn nicht, dann nicht.
Darüber hinaus sind Probleme bei der Mehrfachvererbung vor allem auf Variablen zurückzuführen. Auf jeden Fall haben sie das beschlossen und getan. Beginnend mit JDK 8 führte Java die Möglichkeit ein, Methodenimplementierungen zu Schnittstellen hinzuzufügen.
Hier ist eine aktualisierte Tabelle (für JDK 8 und höher):
Fähigkeit/Eigenschaft | Abstrakte Klassen | Schnittstellen |
---|---|---|
Variablen | ✔ | ✖ |
Methodenimplementierung | ✔ | ✔ |
Mehrfachvererbung | ✖ | ✔ |
Nun können Sie sowohl für abstrakte Klassen als auch für Schnittstellen Methoden mit oder ohne Implementierung deklarieren. Und das sind hervorragende Neuigkeiten!
In abstrakten Klassen muss Methoden ohne Implementierung das abstract
Schlüsselwort vorangestellt werden. Sie müssen vor Methoden mit einer Implementierung nichts hinzufügen. Bei Schnittstellen ist das Gegenteil der Fall. Wenn eine Methode keine Implementierung hat, sollte nichts hinzugefügt werden. Wenn es jedoch eine Implementierung gibt, default
muss das Schlüsselwort hinzugefügt werden.
Der Einfachheit halber stellen wir diese Informationen in der folgenden kleinen Tabelle dar:
Fähigkeit/Eigenschaft | Abstrakte Klassen | Schnittstellen |
---|---|---|
Methoden ohne Implementierung | abstract |
– |
Methoden mit einer Implementierung | – | default |
Problem
Durch die Verwendung von Schnittstellen mit Methoden können große Klassenhierarchien erheblich vereinfacht werden. Beispielsweise können die Zusammenfassung InputStream
und OutputStream
die Klassen als Schnittstellen deklariert werden! Dadurch können wir sie viel häufiger und komfortabler nutzen.
Aber es gibt bereits zig Millionen (Milliarden?) Java-Klassen auf der Welt. Und wenn Sie anfangen, Standardbibliotheken zu ändern, kann es passieren, dass etwas kaputt geht. Wie alles! 😛
Um bestehende Programme und Bibliotheken nicht versehentlich zu beschädigen, wurde beschlossen, dass Methodenimplementierungen in Schnittstellen die niedrigste Vererbungspriorität haben .
Wenn beispielsweise eine Schnittstelle eine andere Schnittstelle erbt, die über eine Methode verfügt, und die erste Schnittstelle dieselbe Methode deklariert, jedoch ohne Implementierung, erreicht die Methodenimplementierung der geerbten Schnittstelle die erbende Schnittstelle nicht. Beispiel:
interface Pet
{
default void meow()
{
System.out.println("Meow");
}
}
interface Cat extends Pet
{
void meow(); // Here we override the default implementation by omitting an implementation
}
class Tom implements Cat
{
}
Der Code lässt sich nicht kompilieren, da die Tom
Klasse die Methode nicht implementiert meow()
.
GO TO FULL VERSION