Interfaces en Java
Aprende a usar interfaces para definir comportamientos específicos y cómo agrupar objetos por capacidades.
Introducción
A diferencia de las clases abstractas, las interfaces no representan jerarquías, sino **capacidades específicas** que una clase puede tener. Por ejemplo, una clase puede ser “voladora” o “nadadora” sin importar su tipo.
¿Qué es una interfaz?
Es una especie de contrato que obliga a las clases que lo implementan a definir ciertos métodos. Se usa cuando quieres definir un comportamiento sin preocuparte de cómo se implementa.
- Se declara con
interface
. - Solo define métodos públicos y constantes.
- Se implementa con la palabra
implements
.
Ejemplo con comportamiento
Si modelamos animales, podríamos tener interfaces como Volador
, Nadador
, Corredor
. Cualquier clase puede implementar una o varias interfaces sin importar su lugar en una jerarquía.
// 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();
¿Cuándo usar interfaces?
- Cuando varias clases no relacionadas comparten un comportamiento.
- Cuando necesitas **flexibilidad múltiple** (Java no permite herencia múltiple, pero sí múltiples interfaces).
- Cuando estás diseñando **APIs públicas** o librerías extensibles.
Diferencias clave: Abstract class vs Interface
Clase abstracta | Interfaz | |
---|---|---|
Jerarquía | Una sola clase base | Varias interfaces |
Implementación | Puede tener lógica interna | No tiene (hasta Java 8+ con default) |
Herencia | extends | implements |
Buenas prácticas
- Nombrar interfaces como comportamientos:
Volador
,Pagable
,Serializable
. - No abuses de interfaces vacías (conocidas como *marker interfaces*), a menos que tengas un propósito claro (como
Serializable
). - Prefiere interfaces cuando necesitas una forma de “agrupar” objetos por capacidades.
- Usa interfaces para definir contratos entre módulos.
Errores comunes
- Usar interfaces cuando deberías usar herencia (ej: una jerarquía real como
Animal
→Perro
). - Repetir lógica en todas las clases que implementan una interfaz (ahí deberías usar una clase abstracta).
- No documentar qué se espera de los métodos de una interfaz (buenas interfaces necesitan buenas descripciones).
Nota Importante
Las interfaces no son sustituto de la herencia. Úsalas para modelar capacidades, no relaciones.
Conclusión
Las interfaces son herramientas muy poderosas para escribir código flexible y orientado a comportamientos. Gracias a ellas puedes aplicar principios como el de programar para una interfaz, no una implementación, lo que facilita la mantenibilidad y las pruebas.
En el próximo capítulo exploraremos colecciones como List
, Set
, Map
y cómo organizar datos de forma eficiente.