Implementación de Interfaces
Parte de la sección Programación Orientada a Objetos del Journey de Java de Coddy — lección 35 de 87.
Para usar una interfaz, una clase debe implementarla usando la palabra clave implements. La clase entonces proporciona implementaciones concretas para todos los métodos declarados en la interfaz:
public interface Drawable {
void draw();
}
public class Circle implements Drawable {
private double radius;
public Circle(double radius) {
this.radius = radius;
}
@Override
public void draw() {
System.out.println("Drawing a circle with radius " + radius);
}
}Si una clase implementa una interfaz pero no proporciona implementaciones para todos sus métodos, el compilador arrojará un error. La anotación @Override es opcional pero se recomienda, ya que ayuda a detectar errores.
Al igual que con las clases abstractas, puedes usar una interfaz como un tipo de referencia. Esto permite el polimorfismo, donde diferentes clases que implementan la misma interfaz pueden ser tratadas de manera uniforme:
Drawable shape1 = new Circle(5.0);
Drawable shape2 = new Rectangle(4.0, 3.0);
shape1.draw(); // Dibujando un círculo con radio 5.0
shape2.draw(); // Dibujando un rectángulo 4.0 x 3.0Esto es potente porque el código que trabaja con referencias Drawable no necesita conocer el tipo de clase específico. Solo le importa que el objeto se pueda dibujar.
En la siguiente lección, verás cómo una sola clase puede implementar múltiples interfaces simultáneamente.
Desafío
FácilVamos a construir un sistema de altavoces que demuestre cómo las clases implementan interfaces. Crearás una interfaz que defina lo que cualquier altavoz puede hacer, luego construirás dos tipos de altavoces diferentes que implementen cada uno este contrato a su manera.
Organizarás tu código en cuatro archivos:
Speaker.java: Define una interfaz llamadaSpeakerque declare lo que cualquier altavoz debe poder hacer. Cada altavoz debe tener un métodospeak()que devuelva un String; este es el contrato que todas las clases implementadoras deben cumplir.Human.java: Crea una clase que implemente la interfazSpeaker. Un Human tiene un camponame(String). Incluye un constructor para inicializar el nombre e implementa el métodospeak()para que devuelva:[name] says: Hello everyone!Robot.java: Crea otra clase que implemente la interfazSpeaker. Un Robot tiene un campomodel(String). Incluye un constructor para inicializar el modelo e implementa el métodospeak()para que devuelva:Robot [model] says: Beep boop!Main.java: Reúne todo utilizando polimorfismo basado en interfaces. Recibirás dos entradas: un nombre humano y un modelo de robot. Crea un Human y un Robot, luego almacénalos en un arreglo de referencias de tipoSpeaker. Recorre el arreglo e imprime el resultado de llamar aspeak()en cada altavoz.
Recibirás dos entradas: el nombre del humano (String) y el modelo del robot (String).
Tu salida debe mostrar dos líneas, una para cada altavoz. ¡Observa cómo tanto el Human como el Robot pueden ser tratados de manera uniforme a través de la interfaz Speaker, a pesar de que hablan de formas completamente diferentes!
Hoja de referencia
Una clase utiliza la palabra clave implements para implementar una interfaz y debe proporcionar implementaciones concretas para todos los métodos declarados en la interfaz:
public interface Drawable {
void draw();
}
public class Circle implements Drawable {
private double radius;
public Circle(double radius) {
this.radius = radius;
}
@Override
public void draw() {
System.out.println("Drawing a circle with radius " + radius);
}
}La anotación @Override es opcional pero recomendada, ya que ayuda a detectar errores.
Las interfaces pueden utilizarse como tipos de referencia, lo que permite el polimorfismo, donde diferentes clases que implementan la misma interfaz pueden tratarse de manera uniforme:
Drawable shape1 = new Circle(5.0);
Drawable shape2 = new Rectangle(4.0, 3.0);
shape1.draw(); // Dibujando un círculo con radio 5.0
shape2.draw(); // Dibujando un rectángulo 4.0 x 3.0Pruébalo tú mismo
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// Leer entradas
String humanName = scanner.nextLine();
String robotModel = scanner.nextLine();
// TODO: Create un objeto Human con el nombre dado
// TODO: Create un objeto Robot con el modelo dado
// TODO: Create un array de referencias Speaker que contenga ambos objetos
// TODO: Recorrer el array e imprimir el resultado de speak() para cada speaker
}
}
Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.
Todas las lecciones de Programación Orientada a Objetos
1Fundamentos de OOP
Archivos externosIntroducción a la OOPClases vs. ObjetosLa palabra clave thisMétodosCampos (Atributos)Método constructorSobrecarga de constructoresResumen - Calculadora simple4Herencia
Herencia básica (extends)La palabra clave superSobrescritura de métodos (@Override)Encadenamiento de constructoresLa clase ObjectHerencia simple y multinivelPor qué no hay herencia múltiple de clasesResumen - Jerarquía de empleados7Métodos especiales y la clase Object
Método toString()equals() y hashCode()Método clone()compareTo() y ComparableInterfaz ComparatorResumen - Ordenamiento personalizado2Modificadores de acceso y encapsulamiento
Visión general de los niveles de accesoMétodos Getter y SetterOcultamiento de informaciónLa palabra clave finalResumen - Gestor de cuentas bancarias5Polimorfismo
Fundamentos de sobrecarga de métodosSobrescritura de métodos (tiempo de ejecución)Upcasting y DowncastingEl operador instanceofClases y métodos abstractosResumen - Calculadora de figuras8Conceptos avanzados de POO
Composición vs. HerenciaAgregación vs. ComposiciónClases internas, anidadas y anónimasEnums y métodos de EnumRecords (Java 16+)Clases selladas (Java 17+)11Patrones de diseño - Parte 1
Introducción a los patrones de diseñoPatrón SingletonPatrón FactoryPatrón BuilderPatrón ObserverPatrón Strategy3Propiedades de clase y miembros estáticos
Variables de instancia vs. estáticasMétodos estáticosBloques estáticosConstantes (static final)Repaso - Contador y utilidad6Interfaces y Clases Abstractas
Introducción a las InterfacesImplementación de InterfacesImplementación de Múltiples InterfacesMétodos Default y Static en InterfacesClases Abstractas vs InterfacesInterfaces FuncionalesResumen - Sistema de Pagos9Genéricos
Introducción a los genéricosClases genéricasMétodos genéricosParámetros de tipo delimitadosComodines (?, extends, super)Resumen - Contenedor genérico12Patrones de diseño Parte 2
Patrón CommandPatrón AdapterPatrón DecoratorPatrón Template MethodPatrón StatePatrón CompositePatrón Iterator