Volver a Java Básico

Introducción

Las interfaces te permiten definir comportamientos específicos que las clases pueden implementar. A diferencia de la herencia, una clase puede implementar múltiples interfaces, proporcionando gran flexibilidad.

Definición de Interfaces

Una interfaz es un contrato que define qué métodos debe implementar una clase, pero no cómo.

// Definimos interfaces que representan capacidades específicas public interface Volador { void volar(); } public interface Nadador { void nadar(); } public interface Corredor { void correr(); } // Clases que implementan interfaces según su comportamiento public class Aguila implements Volador { public void volar() { System.out.println("El águila vuela alto en el cielo."); } } public class Delfin implements Nadador { public void nadar() { System.out.println("El delfín nada rápidamente en el océano."); } } public class Perro implements Corredor, Nadador { public void correr() { System.out.println("El perro corre feliz por el parque."); } public void nadar() { System.out.println("El perro nada en el lago."); } } // Uso práctico Volador ave = new Aguila(); ave.volar(); Nadador mamifero = new Delfin(); mamifero.nadar(); Perro firulais = new Perro(); firulais.correr(); firulais.nadar();

Interfaces vs Clases Abstractas

Interfaces:

  • Definen qué puede hacer una clase (capacidades)
  • Una clase puede implementar múltiples interfaces
  • Todos los métodos son públicos y abstractos por defecto
  • No pueden tener variables de instancia (solo constantes)

Clases Abstractas:

  • Definen qué es una clase (identidad)
  • Una clase solo puede extender una clase abstracta
  • Pueden tener métodos concretos y abstractos
  • Pueden tener variables de instancia y estado

Buenas Prácticas

  • Usa interfaces para definir capacidades o contratos
  • Nombra interfaces basándote en el comportamiento (Legible, Cerrable, Serializable)
  • Mantén las interfaces pequeñas y enfocadas (Principio de Segregación de Interfaces)
  • Usa múltiples interfaces para componer comportamientos complejos
  • Prefiere interfaces sobre clases abstractas para mayor flexibilidad

Malas Prácticas Comunes

  • Crear interfaces con demasiados métodos
  • Usar interfaces cuando una clase simple sería suficiente
  • No usar la anotación @Override al implementar
  • Confundir interfaces con clases abstractas

Ejemplo Práctico

En un sistema de plugins, podrías querer que diferentes componentes tengan capacidad de logging:

public interface Registrable { void registrar(String mensaje); } public class GestorArchivos implements Registrable { public void registrar(String mensaje) { System.out.println("[GestorArchivos] " + mensaje); } public void guardarArchivo(String ruta) { registrar("Guardando archivo: " + ruta); // Lógica de guardado } } public class GestorBaseDatos implements Registrable { public void registrar(String mensaje) { System.out.println("[GestorBaseDatos] " + mensaje); } public void ejecutarConsulta(String consulta) { registrar("Ejecutando consulta: " + consulta); // Lógica de ejecución } }

Conclusión

Las interfaces son esenciales para crear código flexible y modular. Te permiten definir contratos que las clases deben cumplir y habilitan patrones de diseño poderosos como inyección de dependencias y patrón estrategia.

En el próximo capítulo, exploraremos bucles y cómo iterar eficientemente sobre colecciones.