La posibilidad de agregar la implementación de métodos por default en una interface fue añadido en JDK 8 de forma que estas pueden evolucionar sin romper compatibilidad con versiones anteriores. Previamente, no se podía agregar un método a una interface sin requerir que se implementen todos los métodos por parte de la clase que llama a la interface. Una de las principales preocupaciones de Java es no romper la compatibilidad hacia atrás. Entonces, desde la versión 1.8 se puede marcar un método con la palabra reservada default y proporcionar la implementación correcta del método en la interface. Esto utilizado de una forma no adecuada puede generar código que sea difícil de entender y darle mantenimiento. Sin embargo implementado en pequeñas dosis puede hacer a las interfaces más útiles.
La regla principal para utilizar los métodos default sería no abusar de ellos y no hacer el código más desordenado de lo que sería sin él. Por ejemplo, si se desea agregar funcionalidad de ordenamiento a las clases Java sin contaminar la jerarquía con una clase común, considere crear una interface con este único método. A continuación un ejemplo de la interface Debuggable que utiliza el API reflection que accede a los atributos de los objetos y proporciona una implementación de toString() a fin de que el objeto imprima los valores de los campos.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | public interface Debuggable { default String debug() { StringBuilder sb = new StringBuilder(this.getClass().getName()); sb.append(" [ "); Field[] fields = this.getClass().getDeclaredFields(); for(Field f: fields) { f.setAccessible(true); try { sb.append(f.getName() + " = " + f.get(this)); sb.append(", "); } catch (IllegalArgumentException | IllegalAccessException e) { throw new RuntimeException(e); } } sb.append("]"); return sb.toString(); } } |
La parte importante aquí es la palabra reservada default en la firma del método. Ahora se podrá utilizar el método en cualquier otra clase que se requiera para echar un vistazo, tal como:
1 2 3 4 5 6 7 8 9 | public class Main implements Debuggable { int a = 100; String b = "Home"; public static void main(String[] args) { Main m = new Main(); System.out.println(m.debug()); } } |
La cual imprime:
1 | Main [ a = 100 b = Home ] |
Las interfaces funcionales de Java 8 merecen una mención especial aquí. Una interface funcional es aquella que declara un simple método del tipo abstract. Este método puede ser llamado si se utiliza la sintaxis para lambda en forma posterior. Observe que los método default no rompen el contrato de la implementación de un único método abstract. Se puede tener una interface funcional que tiene muchos métodos default de ser necesario. No sobre utilice esta idea. Codificar en forma conciente es importante.
Articulo basado en Java 8 Best Practices Cheat Sheet.