Contenido del curso
Pensando en objetos
Construcción de clases y modelado de objetos
- 10

Métodos estáticos para clases utilitarias en Java
08:43 min - 11

Constantes en Java: inmutabilidad con static final
04:08 min - 12

Constructores en Java para objetos con datos
08:10 min - 13

Gestión de memoria en Java: stack, heap y garbage collector
07:04 min - 14

Encapsulamiento en Java: Atributos privados y métodos getter y setter
09:26 min - 15

Listas en Java: agregar, recorrer y eliminar
11:12 min - 16

Asociación, agregación y composición en Java
03:45 min - 17

Menú interactivo en Java con switch
11:37 min - 18

Buscar y eliminar películas en Java
09:20 min
Estructuras de datos y Java moderno
- 19

Streams y lambdas para filtrar listas en Java
11:55 min - 20

Ordenar y transformar listas con streams en Java
11:49 min - 21

Validación de entrada con enums en Java
11:56 min - 22

Excepciones personalizadas en Java
08:16 min - 23

Records para simplificar código inmutable en Java
06:59 min - 24

Mapas en Java para contar visualizaciones de películas
09:47 min - 25

Leer archivos planos con Java nio
13:48 min - 26

Escribir en archivos planos con Files.writeString
09:50 min
Reutilización y diseño orientado a objetos
Interfaces en Java para código desacoplado
Resumen
Las interfaces en Java te permiten compartir comportamientos entre clases que no tienen relación de herencia, lo que hace tu código más flexible, extensible y fácil de mantener. Si vienes programando en Java y quieres dar el salto hacia decisiones de arquitectura, dominar este recurso es clave para escribir software desacoplado y reutilizable.
¿Qué es una interfaz en Java y cuándo usarla?
Una interfaz define un contrato: un conjunto de métodos que cualquier clase puede implementar sin importar de qué herede. Es ideal cuando varias clases distintas necesitan compartir una capacidad, pero no comparten una jerarquía común.
En el ejemplo de la plataforma Platzi Play, queremos destacar documentales como contenido promocional. En lugar de acoplar un método específico a la clase Documental, creamos una estructura más general que en el futuro permita promocionar otros tipos de contenido sin reescribir lógica.
¿Qué diferencia hay entre una clase abstracta y una interfaz? Una clase abstracta puede tener estado y obliga a heredar; una interfaz solo define comportamiento y puede ser implementada por clases que ya extienden de otras.
¿Cómo se declara una interfaz paso a paso?
Dentro del paquete contenido creamos una nueva Java class, pero seleccionamos el tipo interface. La palabra reservada interface aparece después del modificador de acceso. Así se ve la estructura mínima:
java public interface Promocionable { String promocionar(); }
Nota que el método promocionar no lleva modificador de acceso ni cuerpo. Solo declaramos qué retorna y cómo se llama, igual que un método abstracto, pero más limpio.
¿Cómo implementar una interfaz en una clase existente?
La clase Documental ya extiende de Contenido. Para sumarle la capacidad de promocionarse, agregamos implements Promocionable. Esto obliga a la clase a definir el cuerpo del método declarado en la interfaz.
java public class Documental extends Contenido implements Promocionable { @Override public String promocionar() { return "🎬 Descubre el documental " + this.getTitulo() + " narrado por " + narrador + " ahora en Platzi Play"; } }
Aquí pasa algo importante: Documental hereda de Contenido y al mismo tiempo implementa Promocionable. Java no permite herencia múltiple de clases, pero sí permite implementar varias interfaces a la vez.
¿Cómo filtrar objetos por interfaz con streams?
En la clase Plataforma necesitamos un método que devuelva solo los contenidos promocionables. Usamos instanceof para filtrar y luego casteamos al tipo correcto.
java public List<Promocionable> getContenidoPromocionable() { return contenido.stream() .filter(c -> c instanceof Promocionable) .map(c -> (Promocionable) c) .toList(); }
Este enfoque baja el acoplamiento: el método promocionar no está amarrado a un tipo específico, sino a cualquier clase que decida implementar la interfaz.
¿Cómo consumir el contenido promocional desde main?
En la clase Main, recorremos la lista con un forEach y llamamos al método promocionar de cada elemento. Como retorna un String, lo envolvemos en System.out.println.
java Plataforma.getContenidoPromocionable() .forEach(promocionable -> System.out.println(promocionable.promocionar()));
Al ejecutar, después del mensaje de minutos totales aparece: Descubre el documental Oasis, narrado por Alejandro Ramírez, ahora en Platzi Play. El contenido promocional ya se muestra al iniciar la aplicación.
¿Cuándo conviene usar
instanceofcon interfaces? Cuando trabajas con colecciones heterogéneas y necesitas operar solo sobre los objetos que cumplen un contrato específico, sin importar su clase concreta.
¿Por qué las interfaces aplican el principio de inversión de dependencias?
Un caso muy común es el de los servicios de pago en línea. Imagina que tu sistema acepta Stripe, PayPal, tarjeta de crédito y tarjeta de débito. Todos pueden implementar una misma interfaz llamada ServicioDePagosEnLinea con el método procesarPago.
Tu sistema habla en términos generales: solo quiere procesar un pago, sin preocuparse por los detalles internos de cada proveedor. Esto te da tres beneficios concretos:
- Bajo acoplamiento: el sistema no sabe cómo paga cada proveedor por dentro.
- Alta extensibilidad: puedes agregar nuevos métodos de pago sin tocar los existentes.
- Inversión de dependencias: dependes de abstracciones (interfaces), no de implementaciones concretas, uno de los principios SOLID.
Este tipo de decisiones ya no son solo de código: impactan la arquitectura de tu aplicación. No necesitas ser arquitecto de software para empezar a aplicarlas. Con práctica y buenos hábitos, pensar en interfaces se vuelve parte natural de tu estilo de programar.
¿En qué parte de tu proyecto actual podrías reemplazar una dependencia concreta por una interfaz? Cuéntame en los comentarios cómo lo aplicarías.