Implementación de Múltiples Interfaces
Parte de la sección Programación Orientada a Objetos del Journey de Java de Coddy — lección 36 de 87.
A diferencia de la herencia de clases, donde solo se puede extender una clase, Java permite que una clase implemente múltiples interfaces. Así es como Java logra una forma de herencia múltiple de manera segura.
Para implementar múltiples interfaces, enumérelas después de la palabra clave implements, separadas por comas:
public interface Drawable {
void draw();
}
public interface Resizable {
void resize(int width, int height);
}
public class Rectangle implements Drawable, Resizable {
private int width, height;
public Rectangle(int width, int height) {
this.width = width;
this.height = height;
}
@Override
public void draw() {
System.out.println("Drawing rectangle " + width + "x" + height);
}
@Override
public void resize(int width, int height) {
this.width = width;
this.height = height;
}
}La clase debe implementar todos los métodos de cada interfaz que declare. También puedes combinar la herencia con múltiples interfaces:
public class Square extends Shape implements Drawable, Resizable {
// Debe implementar métodos de ambas interfaces
// También puede usar miembros heredados de Shape
}Esta flexibilidad le permite diseñar clases que cumplen múltiples roles. Un SmartPhone podría implementar las interfaces Callable, Messageable y Browsable, cada una definiendo diferentes capacidades que el teléfono admite.
Desafío
FácilVamos a construir un sistema de dispositivos inteligentes donde los dispositivos pueden tener múltiples capacidades. Crearás una SmartTV que puede encenderse/apagarse y controlar su volumen, demostrando cómo una sola clase puede implementar múltiples interfaces para cumplir diferentes roles.
Organizarás tu código en cuatro archivos:
Powerable.java: Define una interfaz para dispositivos que pueden ser alimentados. Debe declarar dos métodos:powerOn()ypowerOff(), ambos retornando void.VolumeControl.java: Define una interfaz para dispositivos con control de volumen. Debe declarar un métodosetVolume(int level)que retorne void, y un métodogetVolume()que retorne un int.SmartTV.java: Crea una clase que implemente las interfacesPowerableyVolumeControl. Tu SmartTV debe tener un campobrand(String), un campoisOn(boolean, inicialmente false), y un campovolume(int, inicialmente 0). Incluye un constructor que reciba el nombre de la marca. Implementa todos los métodos requeridos:powerOn()debe establecerisOna true e imprimir:[brand] TV is now ONpowerOff()debe establecerisOna false e imprimir:[brand] TV is now OFFsetVolume(int level)debe actualizar el volumen e imprimir:[brand] TV volume set to [level]getVolume()debe retornar el volumen actual
Main.java: Une todo para demostrar la implementación de múltiples interfaces. Recibirás dos entradas: un nombre de marca (String) y un nivel de volumen (int). Crea una SmartTV con la marca dada, luego:- Llama a
powerOn() - Llama a
setVolume()con el nivel dado - Imprime:
Current volume: [volume]usandogetVolume() - Llama a
powerOff()
- Llama a
Recibirás dos entradas: la marca de la TV (String) y el nivel de volumen (int).
Tu salida debe mostrar cuatro líneas demostrando cómo tu SmartTV cumple con ambos contratos de interfaz: ¡puede encenderse como cualquier dispositivo Powerable y controlar su volumen como cualquier dispositivo VolumeControl!
Hoja de referencia
Una clase puede implementar múltiples interfaces enumerándolas después de la palabra clave implements, separadas por comas:
public class Rectangle implements Drawable, Resizable {
// Debe implementar todos los métodos de ambas interfaces
}La clase debe implementar todos los métodos de cada interfaz que declare.
También puedes combinar la herencia de clases con la implementación de múltiples interfaces:
public class Square extends Shape implements Drawable, Resizable {
// Implementa métodos de ambas interfaces
// Puede usar miembros heredados de Shape
}Esto permite que una clase cumpla múltiples roles y tenga diferentes capacidades.
Pruébalo tú mismo
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// Leer las entradas
String brand = scanner.nextLine();
int volumeLevel = scanner.nextInt();
// TODO: Crear una SmartTV con la marca dada
// TODO: Llamar a powerOn()
// TODO: Llamar a setVolume() con el nivel dado
// TODO: Imprimir: Current volume: [volume] usando getVolume()
// TODO: Llamar a powerOff()
}
}
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