In Java 8 e versioni successive, la risposta a questa domanda è ancora valida ma ora è più sfumata.
Innanzitutto, queste affermazioni dalla risposta accettata rimangono corrette:
- le interfacce hanno lo scopo di specificare i loro comportamenti impliciti in un contratto (una dichiarazione di regole per il comportamento che le classi di implementazione devono obbedire per essere considerate valide)
- c'è una distinzione tra contratto (regole) e implementazione (codifica programmatica delle regole)
- i metodi specificati nell'interfaccia DEVONO SEMPRE essere implementati (ad un certo punto)
Quindi, qual è la sfumatura di nuovo in Java 8? Quando si parla di "Metodi opzionali", uno dei seguenti è ora appropriato:
1. Un metodo la cui implementazione è contrattualmente facoltativa
La "terza affermazione" dice che i metodi di interfaccia astratti devono essere sempre implementati e questo rimane vero in Java 8+. Tuttavia, come nel Java Collections Framework, è possibile descrivere alcuni metodi di interfaccia astratti come "opzionali" nel contratto.
In questo caso, l'autore che sta implementando l'interfaccia può scegliere di non implementare il metodo. Il compilatore insisterà su un'implementazione, tuttavia, e quindi l'autore usa questo codice per tutti i metodi opzionali che non sono necessari nella particolare classe di implementazione:
public SomeReturnType optionalInterfaceMethodA(...) {
throw new UnsupportedOperationException();
}
In Java 7 e versioni precedenti, questo era davvero l'unico tipo di "metodo opzionale" disponibile, ovvero un metodo che, se non implementato, generava un'eccezione UnsupportedOperationException. Questo comportamento è necessariamente specificato dal contratto dell'interfaccia (ad es. I metodi di interfaccia opzionali di Java Collections Framework).
2. Un metodo predefinito la cui reimplementazione è facoltativa
Java 8 ha introdotto il concetto di metodi predefiniti . Si tratta di metodi la cui implementazione può essere ed è fornita dalla definizione dell'interfaccia stessa. In genere è possibile fornire metodi predefiniti solo quando il corpo del metodo può essere scritto utilizzando altri metodi di interfaccia (ad esempio, le "primitive") e quando this
può significare "questo oggetto la cui classe ha implementato questa interfaccia".
Un metodo predefinito deve soddisfare il contratto dell'interfaccia (proprio come qualsiasi altra implementazione del metodo di interfaccia deve). Pertanto, specificare un'implementazione del metodo di interfaccia in una classe di implementazione è a discrezione dell'autore (purché il comportamento sia adatto al suo scopo).
In questo nuovo ambiente, il Java Collections Framework potrebbe essere riscritto come:
public interface List<E> {
:
:
default public boolean add(E element) {
throw new UnsupportedOperationException();
}
:
:
}
In questo modo, il metodo "opzionale" add()
ha il comportamento predefinito di lanciare un'eccezione UnsupportedOperationException se la classe di implementazione non fornisce alcun nuovo comportamento, che è esattamente quello che vorresti che accadesse e che è conforme al contratto per List. Se un autore sta scrivendo una classe che non consente l'aggiunta di nuovi elementi a un'implementazione di List, l'implementazione di add()
è facoltativa perché il comportamento predefinito è esattamente ciò che è necessario.
In questo caso, la "terza affermazione" di cui sopra è ancora vera, perché il metodo è stato implementato nell'interfaccia stessa.
3. Un metodo che restituisce un Optional
risultato
L'ultimo nuovo tipo di metodo opzionale è semplicemente un metodo che restituisce un file Optional
. La Optional
classe fornisce un modo decisamente più orientato agli oggetti di trattare i null
risultati.
In uno stile di programmazione fluente, come il tipo comunemente visto quando si codifica con la nuova API Java Streams, un risultato nullo in qualsiasi momento causa l'arresto anomalo del programma con una NullPointerException. La Optional
classe fornisce un meccanismo per restituire risultati nulli al codice client in un modo che consente lo stile fluente senza causare il blocco del codice client.