Entendiendo las Interfaces en Java: Definiciones, Usos y Buenas Prácticas
Una interfaz es un tipo de referencia en Java, similar a una clase, pero es una colección de métodos abstractos. Una clase implementa una interfaz, heredando así sus métodos abstractos.
Además de métodos abstractos, una interfaz puede contener: constantes (static final), métodos default (Java 8+), métodos static (Java 8+) y tipos anidados. Solo los métodos default y static tienen cuerpo.
Similitudes y Diferencias con Clases
| Similitudes | Diferencias |
|---|---|
| Puede tener múltiples métodos | No se puede instanciar |
Archivo .java con mismo nombre | No tiene constructores |
Genera archivo .class | Todos sus métodos son implícitamente abstract (salvo default/static) |
| Aparece en paquetes | No puede tener campos de instancia (solo static final) |
| Se implementa, no se extiende (por clases) | |
| Puede extender múltiples interfaces |
Declaración de Interfaces
Palabra clave: interface.
Ejemplo Básico
public interface Animal {
void eat();
void travel();
}
Propiedades implícitas:
- La interfaz es
abstractimplícitamente. - Cada método es
public abstractimplícitamente.
Implementación de Interfaces
Palabra clave: implements. La clase "firma un contrato" comprometiéndose a implementar todos los métodos (salvo que sea abstracta).
Ejemplo
public class MammalInt implements Animal {
public void eat() {
System.out.println("Mamífero come");
}
public void travel() {
System.out.println("Mamífero viaja");
}
public int noOfLegs() { return 0; }
public static void main(String args[]) {
MammalInt m = new MammalInt();
m.eat();
m.travel();
}
}
Salida:
Mamífero come Mamífero viaja
Reglas al Sobrescribir Métodos de Interfaz
- Excepciones verificadas: solo las declaradas en la interfaz o subclases de estas.
- Mantener firma y tipo de retorno (o subtipo).
- La clase implementadora puede ser abstracta (diferir implementación).
Reglas de Implementación
- Una clase puede implementar múltiples interfaces.
- Una clase extiende una sola clase, pero implementa muchas interfaces.
- Una interfaz puede extender otra interfaz (herencia de interfaces).
Extensión de Interfaces
Una interfaz puede extender otra con extends. La interfaz hija hereda los métodos de la padre.
Ejemplo: Jerarquía Sports → Football / Hockey
public interface Sports {
void setHomeTeam(String name);
void setVisitingTeam(String name);
}
public interface Football extends Sports {
void homeTeamScored(int points);
void visitingTeamScored(int points);
void endOfQuarter(int quarter);
}
public interface Hockey extends Sports {
void homeGoalScored();
void visitingGoalScored();
void endOfPeriod(int period);
void overtimePeriod(int ot);
}
Una clase que implemente Hockey debe implementar sus 4 métodos + 2 de Sports = 6 métodos.
Extensión Múltiple de Interfaces
Una interfaz sí puede extender varias interfaces (lista separada por comas).
public interface Hockey extends Sports, Event { ... }
Interfaces de Marcado (Tagging Interfaces)
Una interfaz sin métodos se llama tagging interface (interfaz de marcado). Ejemplo clásico: java.util.EventListener.
package java.util;
public interface EventListener {}
Dos Propósitos de Diseño
- Padre común: Agrupa interfaces relacionadas (ej. listeners de eventos). La JVM sabe que una interfaz que extiende
EventListenerse usará en delegación de eventos. - Añadir tipo de dato a una clase: Una clase que implementa una interfaz de marcado no define métodos, pero adquiere ese tipo vía polimorfismo. Ejemplo:
Serializable,Cloneable.
Métodos Default y Static en Interfaces (Java 8+)
Permiten añadir implementación a interfaces sin romper clases existentes.
Método Default
interface Vehicle {
default void printType() {
System.out.println("Soy un vehículo");
}
}
Las clases que implementan Vehicle heredan printType() salvo que lo sobrescriban.
Método Static
interface Utils {
static String format(String s) { return s.trim().toUpperCase(); }
}
// Uso: Utils.format(" hola ")
Los métodos static de interfaz se invocan como InterfaceName.method() y no se heredan.
Interfaces Funcionales (Functional Interfaces)
Una interfaz con exactamente un método abstracto (puede tener default/static). Base para expresiones lambda y referencias a métodos. Anotación opcional: @FunctionalInterface.
@FunctionalInterface
interface Calculator {
int operate(int a, int b);
}
// Uso con lambda
Calculator sum = (a, b) -> a + b;
Calculator mul = (a, b) -> a * b;
Java
- Palabra clave final en Java: Variables, métodos y clases
- Operador instanceof en Java: Guía completa
- Dominando interfaces en Java: Conceptos, implementación y mejores prácticas
- Entendiendo las clases anidadas estáticas en Java: Uso, diferencias y ejemplos
- Dominando las clases internas anónimas en Java: Definición, sintaxis y ejemplos prácticos
- Patrón Singleton en Java explicado: Cómo implementarlo y usarlo de forma segura
- Dominando la Reflexión en Java: Inspeccionando clases, métodos y campos en tiempo de ejecución
- Dominando ObjectOutputStream de Java: Serialización, Métodos y Ejemplos Prácticos
- Dominando Java Generics: Construyendo Código Reutilizable y Type-Safe
- Dominando las operaciones de archivos en Java con java.io: creación, lectura, escritura y eliminación
- Interfaz vs Clase Abstracta en Java: Cómo elegir la abstracción correcta