In Java 8 und höher ist die Antwort auf diese Frage noch gültig, aber jetzt nuancierter.
Erstens bleiben diese Aussagen aus der akzeptierten Antwort richtig:
- Schnittstellen sollen ihr implizites Verhalten in einem Vertrag angeben (eine Erklärung der Verhaltensregeln, die implementierende Klassen befolgen müssen, um als gültig zu gelten).
- Es wird zwischen Vertrag (Regeln) und Umsetzung (programmatische Kodierung der Regeln) unterschieden.
- In der Schnittstelle angegebene Methoden MÜSSEN IMMER implementiert werden (irgendwann)
Was ist die Nuance, die in Java 8 neu ist? Wenn von "optionalen Methoden" gesprochen wird, ist jetzt eine der folgenden Optionen geeignet:
1. Eine Methode, deren Implementierung vertraglich optional ist
Die "dritte Aussage" besagt, dass abstrakte Schnittstellenmethoden immer implementiert werden müssen, und dies gilt auch für Java 8+. Wie im Java Collections Framework ist es jedoch möglich, einige abstrakte Schnittstellenmethoden im Vertrag als "optional" zu beschreiben.
In diesem Fall kann der Autor, der die Schnittstelle implementiert, festlegen, dass die Methode nicht implementiert wird. Der Compiler besteht jedoch auf einer Implementierung, und der Autor verwendet diesen Code für alle optionalen Methoden, die in der jeweiligen Implementierungsklasse nicht benötigt werden:
public SomeReturnType optionalInterfaceMethodA(...) {
throw new UnsupportedOperationException();
}
In Java 7 und früheren Versionen war dies wirklich die einzige Art von "optionaler Methode", die es gab, dh eine Methode, die, wenn sie nicht implementiert wurde, eine UnsupportedOperationException auslöste. Dieses Verhalten wird notwendigerweise im Schnittstellenvertrag festgelegt (z. B. die optionalen Schnittstellenmethoden des Java Collections Framework).
2. Eine Standardmethode, deren Neuimplementierung optional ist
Java 8 führte das Konzept der Standardmethoden ein . Dies sind Methoden, deren Implementierung von der Schnittstellendefinition selbst bereitgestellt werden kann und wird. Es ist im Allgemeinen nur möglich, Standardmethoden bereitzustellen, wenn der Methodenkörper mit anderen Schnittstellenmethoden (dh den "Grundelementen") geschrieben werden kann und wenn this
"dieses Objekt, dessen Klasse diese Schnittstelle implementiert hat" bedeutet.
Eine Standardmethode muss den Vertrag der Schnittstelle erfüllen (genau wie jede andere Implementierung der Schnittstellenmethode). Daher liegt es im Ermessen des Autors, eine Implementierung der Schnittstellenmethode in einer implementierenden Klasse anzugeben (sofern das Verhalten für seinen Zweck geeignet ist).
In dieser neuen Umgebung könnte das Java Collections Framework wie folgt umgeschrieben werden:
public interface List<E> {
:
:
default public boolean add(E element) {
throw new UnsupportedOperationException();
}
:
:
}
Auf diese Weise hat die "optionale" Methode add()
das Standardverhalten, eine UnsupportedOperationException auszulösen, wenn die implementierende Klasse kein eigenes neues Verhalten bereitstellt. Dies ist genau das, was Sie sich wünschen würden und was mit dem Vertrag für List kompatibel ist. Wenn ein Autor eine Klasse schreibt, in der keine neuen Elemente zu einer List-Implementierung hinzugefügt werden können, ist die Implementierung von add()
optional, da das Standardverhalten genau das ist, was benötigt wird.
In diesem Fall gilt die obige "dritte Aussage" weiterhin, da die Methode in der Schnittstelle selbst implementiert wurde.
3. Eine Methode, die ein Optional
Ergebnis zurückgibt
Die letzte neue Art der optionalen Methode ist einfach eine Methode, die eine zurückgibt Optional
. Die Optional
Klasse bietet eine deutlich objektorientiertere Möglichkeit, mit null
Ergebnissen umzugehen .
In einem fließenden Programmierstil, wie er üblicherweise beim Codieren mit der neuen Java Streams-API verwendet wird, führt ein Null-Ergebnis zu jedem Zeitpunkt dazu, dass das Programm mit einer NullPointerException abstürzt. Die Optional
Klasse bietet einen Mechanismus zum Zurückgeben von Nullergebnissen an den Clientcode auf eine Weise, die den fließenden Stil ermöglicht, ohne dass der Clientcode abstürzt.