El diseño actual de aplicaciones en Java es impensable sin el uso de las Interfaces, este es uno de los recursos más empleados para desacoplar nuestras aplicaciones y hacer un diseño robusto que posibilite reutilización e introducción de cambios de manera fácil. En esta entrada vamos a hablar de las interfaces, los tipos y su importancia.

¿Qué es una interfaz?

Un aproximación al concepto de Interfaz más general la podemos tomar desde el diccionario de Cambridge:

Mean: a connection between two pieces of electronic equipment, or between a person and a computer:
My computer has a network interface, which allows me to get to other computers.
The new version of the program comes with a much better user interface (= way of showing information to a user) than the original.

Un poco más aterrizado a la programación el concepto no difiere mucho, de ahí que tenga el mismo nombre, podemos resumir a una interfaz como un recurso que señala lo que que hay que hacer, pero sin especificar el “cómo” hacerlo.

Las interfaces tienen una semejanza con las clases abastractas, en el sentido que no pueden ser instanciadas. Las clases asociadas a una interfaz tienen el compromiso de implementar todos los métodos en ellas definidos, pero en este caso la relación no es de herencia en plenitud, dado que no hay atributos en la definición de una interfaz, aunque si pueden haber constantes declaradas.

Las interfaces no son clases, sólo especifican requerimientos para la clase que las implementa. Con la salida de Java 8 se añadieron las interfaces con métodos por defecto, que permiten implementación directa.

Tipos de interfaces

Existen diferentes tipos de interfaces en función de como se declaren, entre las clasificaciones podemos ver:

Interfaces taggeadas o etiquetadas: También conocidas como marker interfaces que carecen de métodos para implementar, están vacías, su función es la de agrupar o servir de raíz para diferentes clases que las “implementen”, ejemplos de interfaces etiquetadas en Java son Seriablizable, Clonnable y Remote.

Interfaces regulares: Son las interfaces normales, que comúnmente se emplean, poseen uno o varios métodos no implementados y pueden poseer (si el language level es >= 1.8) métodos implementados marcados como por defecto (default).

Interfaces funcionales: Las interfaces funcionales fueron añadidas en Java 8 al igual que los métodos por defecto en las interfaces, este tipo de interfaces tienen un solo método y se anotan con @FunctionalInterface.

Las interfaces funcionales y la posibilidad de implementar métodos por defecto en Java 8 surgieron como una solución para dotar el API de Java 8 de los Streams, de no ser por ello todo Collection tenía que ser sobre-escrito ¿se imaginan?

Beneficios de las interfaces como un recurso en Java

Diversas son las ventajas para cualquier lenguaje que brinda la posibilidad de disponer de este recurso, algunas son:

  • Organizar el código.
  • Declarar constantes para todos las clases que las implementen.
  • Permitir el bajo acoplamiento entre los componentes.
  • Establecer relaciones entre clases.
  • Obligar a las clases a implementar métodos con una determinada firma.
  • Establecer contratos a futuro.
  • Son un soporte para la carencia de herencia múltiple que tiene Java.

Ejemplos de interfaces

Ejemplo de interfaz simple, común:

// Ejemplo básico
public interface HealthService {
    boolean getHealthStatus();
    String getServiceInformation();
}
// Ejemplo de interfaz con tipo genérico
public interface EntityRepository<T, ID extends Serializable> {
  Page findAll(Map<String, Object> params);
  T save(T entity);
}

Ejemplo de una interfaz etiquetada

// Ejemplo de interfaz etiquetada
public interface HealthService {
}

Ejemplo de una interfaz funcional

@FunctionalInterface
public interface NetworkStatusService {
boolean getNetworkStatus();
}

En las interfaces, también existe la herencia, y una interfaz puede heredar de otra para ayudar a formar una jerarquía, las interfaces etiquetadas que vimos arriba son comúnmente usadas como la raíz de un árbol de interfaces.

// Ejemplo de interfaces y herencia.
public interface ParentInterface {
  boolean method1();
}
public interface Interface1 extends ParentInterface {
   boolean method2();
}

Esta última posibilidad puede ser usada cuando nos enfrentamos en JPA al uso de projection.

Por último, en Java 8 además de las interfaces funcionales también está disponible colocar en las interfaces métodos estáticos y por defecto.

Un método por defecto (default) es un método que puede ser implementado a nivel de interfaz, la sintaxis y forma se muestran en el siguiente ejemplo.

public interface Room {
    default String openDoor() {
        return "Turning on.";
    }
    default String closeDoor() {
        return "Turning off.";
    }
}

Espero te sirva y sea útil este artículo.

Leave a Reply

Your email address will not be published. Required fields are marked *