1. ¿Qué es una interfaz?
Si una clase abstracta es el plano de una casa, entonces una interfaz es más bien un contrato para realizar determinados trabajos. Por ejemplo, si llamas a un fontanero, esperas que sepa «arreglar el grifo» y «eliminar una fuga». Cómo lo haga —no te importa—, lo importante es el resultado. En Java, una interfaz es precisamente ese contrato: indica qué métodos deben implementarse, pero no dice cómo.
Breve y al grano:
Una interfaz es un tipo especial en Java que define un conjunto de métodos que deben implementar las clases que se suscriben a esa interfaz.
- La interfaz describe solo «qué hacer», no «cómo hacerlo».
- Hasta Java 8, las interfaces no contenían implementación de métodos.
- Una interfaz es un contrato puro: si una clase implementa la interfaz, debe implementar todos sus métodos.
¿Por qué es útil?
- Se pueden «colgar» varias interfaces de una clase —es decir, darle varios «roles».
- Permite construir arquitecturas flexibles y extensibles, donde las clases pueden implementar distintas capacidades.
- Las interfaces se usan ampliamente en la biblioteca estándar de Java (por ejemplo, Comparable, Serializable, Runnable, etc.).
2. Sintaxis de declaración de una interfaz
Declarar una interfaz en Java es muy sencillo. Se utiliza la palabra clave interface. Hasta Java 8, los métodos de una interfaz se consideraban por defecto public abstract, aunque no se indicara explícitamente. Esto significa que el método debe implementarse en la clase que implementa la interfaz.
Ejemplo de interfaz
public interface Movable {
void move(int x, int y);
}
- Aquí declaramos la interfaz Movable (puede traducirse como «móvil» o «que puede moverse»).
- Dentro se declara el método move(int x, int y). No hay cuerpo de método —solo la firma. Ese es el «contrato»: «si implementas Movable, tienes que implementar move».
Particularidades de la sintaxis
- Los métodos en una interfaz no tienen cuerpo (hasta Java 8).
- Todos los métodos de una interfaz son por defecto public abstract (no es necesario escribirlo explícitamente).
- Una interfaz puede contener solo constantes (public static final), no campos normales.
Ejemplo con una constante
public interface Constants {
int MAX_SPEED = 100; // public static final por defecto
}
3. Diferencia entre interfaz y clase
¡Una interfaz no es una clase! Veamos en qué se diferencian.
| Clase (incluida la abstracta) | Interfaz |
|---|---|
| Puede contener campos (estado) | No puede contener campos (solo constantes) |
| Puede contener implementación de métodos | Hasta Java 8, las interfaces no podían contener implementación, solo firmas |
| Se puede crear mediante new (si no es abstracta) | No se puede crear directamente |
| Herencia simple (extends) | Una clase puede implementar varias interfaces (implements) |
| Se usa para «qué es» | Se usa para «qué puede hacer» |
Una clase implementa una interfaz con implements
public class Robot implements Movable {
@Override
public void move(int x, int y) {
System.out.println("El robot se desplaza al punto (" + x + ", " + y + ")");
}
}
- La clase Robot implementa la interfaz Movable.
- La palabra clave implements significa «implementa».
- Es obligatorio implementar todos los métodos de la interfaz (de lo contrario habrá un error de compilación).
- No olvides la anotación @Override: no es obligatoria, pero ayuda al compilador y te evita errores.
4. Ejemplo de uso de una interfaz
Escribamos un ejemplo sencillo para ver cómo funciona en la práctica. Imagina que tenemos la interfaz Movable y queremos que distintas clases puedan «moverse»: un robot, un coche, un animal…
Paso 1. Declaramos la interfaz
public interface Movable {
void move(int x, int y);
}
Paso 2. Implementamos la interfaz en una clase
public class Robot implements Movable {
@Override
public void move(int x, int y) {
System.out.println("El robot se desplaza al punto (" + x + ", " + y + ")");
}
}
Paso 3. Usamos la interfaz
public class Main {
public static void main(String[] args) {
Movable m = new Robot(); // ¡Variable de tipo interfaz!
m.move(10, 20); // Imprimirá: El robot se desplaza al punto (10, 20)
}
}
Presta atención
- Podemos declarar una variable de tipo interfaz (Movable m) y asignarle un objeto de una clase que implementa esa interfaz (new Robot()).
- Esto permite escribir código genérico que funciona con cualquier objeto «móvil», sin saber qué clase es realmente.
Error de compilación si no se implementa el método
Error: Class 'Robot' must either be declared abstract or implement abstract method 'move(int, int)' in 'Movable'
Esa es la fuerza de la interfaz: garantiza que todas las clases que la implementan tengan los métodos necesarios.
5. Interfaces en la biblioteca estándar de Java
Las interfaces no son un tema «escolar». Se usan activamente en toda la biblioteca estándar de Java. Algunos ejemplos:
- Comparable<T> — interfaz para comparar objetos (por ejemplo, al ordenar).
- Runnable — interfaz para ejecutar un hilo.
- Serializable — interfaz marcadora que indica que un objeto se puede serializar.
- List, Set, Map — interfaces de colecciones.
Ejemplo: Comparable
public class Person implements Comparable<Person> {
String name;
int age;
// Constructor y otros métodos...
@Override
public int compareTo(Person other) {
return this.age - other.age;
}
}
Ahora los objetos Person se pueden ordenar porque implementan la interfaz Comparable.
6. Esquema visual: cómo funciona una interfaz
+-------------------+ +-------------------+
| interface | | class |
| Movable |<--------| Robot |
|-------------------| |-------------------|
| +move(int, int) | | +move(int, int) |
+-------------------+ +-------------------+
- La flecha muestra que la clase Robot implementa la interfaz Movable.
- La interfaz define solo «qué debe haber»; la clase, «cómo funciona».
Analogía de la vida real
Una interfaz en Java es como el permiso de conducir. Si tienes el permiso (implementas la interfaz «Conductor»), significa que sabes conducir un coche. Cómo lo haces ya son detalles: algunos conducen con cuidado, otros rápido, pero lo importante es que has aceptado que sabes hacerlo.
7. Ejemplo práctico: continuamos nuestra aplicación
public interface Movable {
void move(int x, int y);
}
public class Animal implements Movable {
protected String name;
public Animal(String name) {
this.name = name;
}
@Override
public void move(int x, int y) {
System.out.println(name + " se desplaza al punto (" + x + ", " + y + ")");
}
}
public class Robot implements Movable {
private String model;
public Robot(String model) {
this.model = model;
}
@Override
public void move(int x, int y) {
System.out.println("El robot " + model + " va hacia las coordenadas (" + x + ", " + y + ")");
}
}
public class Main {
public static void main(String[] args) {
Movable[] movables = {
new Animal("Barsik"),
new Robot("R2D2")
};
for (Movable m : movables) {
m.move(5, 10);
}
}
}
Resultado:
Barsik se desplaza al punto (5, 10)
El robot R2D2 va hacia las coordenadas (5, 10)
Creamos un array de objetos de tipo Movable. ¡En él puede haber cualquier objeto que implemente esa interfaz! El código del bucle no sabe qué tiene delante —un animal o un robot—, pero sabe que cada uno de ellos sabe move.
8. Errores típicos al trabajar con interfaces
Error n.º 1: intentar crear un objeto de una interfaz directamente. Una interfaz es un contrato, no un objeto concreto. No se puede escribir new Movable() —esto producirá un error de compilación. Hay que crear objetos de clases que implementen la interfaz.
Error n.º 2: no se implementan todos los métodos de la interfaz. Si una clase implementa una interfaz pero no implementa todos sus métodos, el compilador mostrará un error: «Class must either be declared abstract or implement abstract method ...». Si no quieres implementar todos los métodos, declara la clase como abstract.
Error n.º 3: olvidar los modificadores de acceso. Los métodos de una interfaz siempre son public (aunque no se escriba explícitamente). En la clase que implementa no se puede reducir el nivel de acceso, por lo que el método también debe ser public.
Error n.º 4: intentar añadir campos normales a una interfaz. En una interfaz solo se pueden declarar constantes (public static final). No se pueden añadir campos normales (no estáticos).
GO TO FULL VERSION