En Java 8 y versiones posteriores, la respuesta a esta pregunta sigue siendo válida, pero ahora tiene más matices.
Primero, estas declaraciones de la respuesta aceptada siguen siendo correctas:
- las interfaces están destinadas a especificar sus comportamientos implícitos en un contrato (una declaración de reglas de comportamiento que las clases de implementación deben obedecer para ser consideradas válidas)
- hay una distinción entre el contrato (reglas) y la implementación (codificación programática de las reglas)
- Los métodos especificados en la interfaz SIEMPRE DEBEN implementarse (en algún momento)
Entonces, ¿cuál es el matiz nuevo en Java 8? Cuando se habla de "métodos opcionales", cualquiera de los siguientes es ahora apto:
1. Un método cuya implementación es contractualmente opcional
La "tercera declaración" dice que los métodos de interfaz abstracta siempre deben implementarse y esto sigue siendo cierto en Java 8+. Sin embargo, como en Java Collections Framework, es posible describir algunos métodos abstractos de interfaz como "opcionales" en el contrato.
En este caso, el autor que está implementando la interfaz puede optar por no implementar el método. Sin embargo, el compilador insistirá en una implementación, por lo que el autor usa este código para cualquier método opcional que no sea necesario en la clase de implementación en particular:
public SomeReturnType optionalInterfaceMethodA(...) {
throw new UnsupportedOperationException();
}
En Java 7 y versiones anteriores, este era realmente el único tipo de "método opcional" que existía, es decir, un método que, si no se implementaba, arrojaba una UnsupportedOperationException. Este comportamiento está necesariamente especificado por el contrato de interfaz (por ejemplo, los métodos de interfaz opcionales de Java Collections Framework).
2. Un método predeterminado cuya reimplementación es opcional
Java 8 introdujo el concepto de métodos predeterminados . Estos son métodos cuya implementación puede ser proporcionada por la propia definición de interfaz. Generalmente, solo es posible proporcionar métodos predeterminados cuando el cuerpo del método se puede escribir usando otros métodos de interfaz (es decir, las "primitivas"), y cuando this
puede significar "este objeto cuya clase ha implementado esta interfaz".
Un método predeterminado debe cumplir con el contrato de la interfaz (como debe hacerlo cualquier otra implementación de método de interfaz). Por lo tanto, especificar una implementación del método de interfaz en una clase de implementación queda a discreción del autor (siempre que el comportamiento sea adecuado para su propósito).
En este nuevo entorno, Java Collections Framework podría reescribirse como:
public interface List<E> {
:
:
default public boolean add(E element) {
throw new UnsupportedOperationException();
}
:
:
}
De esta manera, el método "opcional" add()
tiene el comportamiento predeterminado de lanzar una UnsupportedOperationException si la clase de implementación no proporciona un comportamiento nuevo propio, que es exactamente lo que le gustaría que sucediera y que cumple con el contrato de List. Si un autor está escribiendo una clase que no permite agregar nuevos elementos a una implementación de Lista, la implementación de add()
es opcional porque el comportamiento predeterminado es exactamente lo que se necesita.
En este caso, la "tercera declaración" anterior sigue siendo cierta, porque el método se ha implementado en la propia interfaz.
3. Un método que devuelve un Optional
resultado
El último tipo nuevo de método opcional es simplemente un método que devuelve un Optional
. La Optional
clase proporciona una forma decididamente más orientada a objetos de tratar los null
resultados.
En un estilo de programación fluido, como el que se ve comúnmente al codificar con la nueva API de Java Streams, un resultado nulo en cualquier punto hace que el programa se bloquee con una NullPointerException. La Optional
clase proporciona un mecanismo para devolver resultados nulos al código del cliente de una manera que habilita el estilo fluido sin que el código del cliente se bloquee.