Cuando usar Abstract o Interface



This content originally appeared on DEV Community and was authored by Elías Canales

Java ofrece mucha versatilidad para hacer las cosas de distinta forma. Antes de Java 8 había una gran diferencia entre una clase abstracta y una interfaz. Pero lo cierto es que ahora, la diferencia es más bien pequeña.

Esto es debido principalmente a la definición de métodos por defecto de las interfaces. Antes de la versión 8 las interfaces solo tenían el contrato, pero no definían ninguna función por defecto. Por eso la diferencia era mucho mayor, ya que las clases abstractas pueden tanto definir contratos como implementaciones.

Y aunque las cosas se pueden hacer de distinta forma, a largo plazo, no hay tantas formas que garanticen mantener nuestro código limpio y fácilmente extensible. Por eso, es interesante tener en mente un enfoque a largo plazo pero sin tampoco obsesionarnos, porque los excesos tampoco son buenos.

Abstract class

Las clases abstractas son clases que no pueden instanciarse, las cuales están hechas para ser heredadas y donde las subclases deben definir los métodos del contrato a menos que la clase que herede también sea una clase abstracta.

Interface

Las interfaces son contratos, las clases pueden implementar muchos contratos, por lo que las clases pueden adquirir tipos por medio de las interfaces y hacer algo así como herencia múltiple.

Interfaz vs Abstract class

Como ya comentamos en el artículo sobre “favorecer la composición”, la herencia es peligrosa siempre que no se utiliza con mucho detenimiento. Por eso, las interfaces son mucho mas interesantes a la hora de definir tipos, nos pueden permitir guardar en un listado, elementos de un mismo tipo, o lo que es lo mismo, de una misma interfaz.

Pero tenemos que tener en cuenta, que las interfaces definen todos sus métodos como public por defecto (también permiten private pero solo son accesibles en esa interfaz), no podemos hacer métodos ocultos solo para el paquete o los que lo implementan (protected). Y tampoco podemos sobrescribir métodos estándar del objeto como equals, hashcode…

Las interfaces pueden heredar de otras interfaces, es más, pueden heredar de más de una. Con lo cual podemos juntar tipos para crear nuevos tipos más complejos, sin perder la versatilidad de tener tipos más pequeños.

Entonces, ¿Cuándo son interesantes las interfaces frente a las clases abstractas?

  1. Cuando necesitamos que una clase implemente múltiples tipos
  2. Cuando la funcionalidad no se ajusta a una jerarquía claramente definida, y se requiere un enfoque más flexible basado en contratos
  3. Cuando no necesitas una implementación común
  4. Cuando no necesitas un control detallado sobre la implementación de los métodos

Referencias


This content originally appeared on DEV Community and was authored by Elías Canales