Java 8 – Métodos Default y Static en Interfaces

La nueva versión de Java tiene previsto su lanzamiento para el 18 de Marzo, aunque ya se puede descargar una Beta Version. La característica más conocida de esta nueva versión son las lambdas. Pero tiene otras muchas novedades como un nuevo motor de Javascript, interfaces funcionales, operaciones con grandes cantidades de datos, eliminación del Permagen o la clase Time.

Voy a intentar explicar todas estas características poco a poco, a lo largo de una serie de artículos. Hoy empezaré con un par de mejoras en los interfaces.

Default Methods

Cuando se crea un interfaz se declaran métodos abstractos y son las clases que implementan la interfaz las que añaden la implementación del método. Pero, ¿qué ocurre si queremos añadir un nuevo método a un interfaz?. Lo que hay que hacer es declarar un método abstracto en el interfaz y serán las clases que lo implementen las que tendrán que definir este método. Esto es un problema ya que obliga a cambiar bastante código existente para cada modificación.

Para solucionar este problema se ha añadido la posibilidad de crear métodos default en los interfaces, añadiendo lo que se llama Extensión Virtual de Métodos o Defender Methods. Con los métodos default se proporciona una implementación por defecto de un método, de manera que para añadir una nueva funcionalidad no es necesario que las clases hijas del interfaz definan dicho método.

Para definir métodos en un interfaz se utiliza la palabra default seguida de la firma del método.

En el siguiente ejemplo se ve un interfaz Persona que implementa un método decirHola y a continuación se declara una nueva clase Pedro que implementa el interfaz Persona:

Estos métodos pueden ser ejecutados directamente desde el interfaz sin necesidad de implementarlo en una subclase. Viendo el ejemplo se puede observar que la clase Pedro no tiene que implementar el método decirHola del interfaz. Ésta clase podría llamar al método sin ningún problema:

Veamos otro ejemplo. En el interfaz Iterable se ha añadido el método default forEach:

Cuando se extiende un interfaz que contiene un método default se pueden dar los siguientes casos:

  • Si no se menciona el método default, se utiliza la implementanción del interfaz.
  • Se puede volver a hacer abstracto redefiniendo el método como abstract.
  • Se puede redefinir el método de forma similar a la que se sobrescriben los métodos.
  • Cuando una clase implementa dos interfaces que tienen definido un método default con la misma firma es necesario redefinir el método e indicar a que interfaz llama:
  • En un interfaz no se puede implementar un método default que sobrescribe algún método de la clase Object, como equals, hasCode o toString.

Entonces, ¿cual es la diferencia entre una clase abstracta y un interfaz que implementa métodos default? La diferencia es mínima. Una clase sólo puede extender una clase abstracta pero puede implementar múltiples interfaces. Ademas, en un interfaz no se pueden declarar campos mutables, mientras que si se puede hacer en una clase abstracta.

Los métodos default han sido muy utilizados en la Jdk8, como por ejemplo para la creación del Stream API:

Static Methods

Actualmente en el API de Java existen muchas clases de utilidades usadas para dar soporte a los interfaces implementando métodos estáticos que son utilizados por todas las clases que hereden de ese interfaz. Un ejemplo de ello es la clase Collections que da soporte a todas las clases que heredan del interfaz Collection.

Ahora existe la posibilidad de crear estos métodos estáticos directamente en el interfaz, permitiendo tener una mejor organización del código.

Un ejemplo podría ser el interfaz Collection al que se han añadido dos métodos estáticos, stream y parallelStream. Otro ejemplo es el método naturalOrder añadido a la clase Comparator:

Enlaces |
Documentación Oficial Default Methods
Virtual Extension Method