Interfaces múltiples
Parte de la sección Programación Orientada a Objetos del Journey de Dart de Coddy — lección 48 de 110.
Una de las mayores ventajas de las interfaces sobre la herencia es que una clase puede implementar múltiples interfaces. Mientras que Dart te restringe a extender solo una clase, puedes implementar tantas interfaces como necesites.
abstract class Printable {
void printContent();
}
abstract class Saveable {
void save();
}
abstract class Shareable {
void share(String recipient);
}
class Document implements Printable, Saveable, Shareable {
String content;
Document(this.content);
@override
void printContent() {
print('Printing: $content');
}
@override
void save() {
print('Saving document...');
}
@override
void share(String recipient) {
print('Sharing with $recipient');
}
}Al implementar múltiples interfaces, debe proporcionar implementaciones para todos los métodos de cada interfaz. La clase debe cumplir con todos los contratos que promete soportar.
También puedes combinar extends con múltiples implements:
class Report extends Document implements Printable, Shareable {
Report(String content) : super(content);
// Aún debe implementar todos los métodos de la interfaz
// (ya heredados de Document en este caso)
}Esta flexibilidad te permite diseñar clases que se adaptan a múltiples roles. Un SmartPhone podría implementar las interfaces Camera, Phone y MusicPlayer, prometiendo que puede hacer todo lo que cada interfaz requiere mientras mantiene su propia implementación única.
Desafío
FácilVamos a construir un sistema de dispositivos inteligentes que demuestre cómo una sola clase puede implementar múltiples interfaces para combinar diferentes capacidades. Crearás clases de interfaz separadas para diferentes características de dispositivos y luego construirás un dispositivo que pueda hacerlo todo.
Organizarás tu código en dos archivos:
devices.dart: Define tus interfaces y la clase que las implementa aquí:- Una clase
Connectablecon un métodoconnect()que imprimaConnecting to network... - Una clase
Chargeablecon un métodocharge()que imprimaCharging battery... - Una clase
Displayablecon un métodoshowScreen(String content)que imprimaDisplaying: [content] - Una clase
Tabletque implemente las tres interfaces:Connectable,ChargeableyDisplayable. Añade una propiedadString brandcon un constructor. Tus implementaciones deben imprimir[brand] tablet connecting to WiFipara connect,[brand] tablet charging via USB-Cpara charge, y[brand] screen: [content]para showScreen
- Una clase
main.dart: Importa tu archivo de dispositivos y demuestra cómo la Tablet cumple con los tres contratos de interfaz:- Crea una
Tabletcon la marca'Galaxy' - Llama a
connect() - Llama a
charge() - Llama a
showScreen('Welcome Home')
- Crea una
Tu clase Tablet debe proporcionar su propia implementación para cada método de las tres interfaces. Esto muestra cómo la implementación de múltiples interfaces permite que una sola clase prometa múltiples capacidades manteniendo cada implementación única para el dispositivo.
Salida esperada:
Galaxy tablet connecting to WiFi
Galaxy tablet charging via USB-C
Galaxy screen: Welcome HomeHoja de referencia
Una clase puede implementar múltiples interfaces enumerándolas después de la palabra clave implements, separadas por comas:
abstract class Printable {
void printContent();
}
abstract class Saveable {
void save();
}
class Document implements Printable, Saveable {
@override
void printContent() {
print('Printing...');
}
@override
void save() {
print('Saving...');
}
}Al implementar múltiples interfaces, debes proporcionar implementaciones para todos los métodos de cada interfaz.
Puedes combinar extends con múltiples implements:
class Report extends Document implements Printable, Shareable {
Report(String content) : super(content);
// Debe implementar todos los métodos de la interfaz
}Esto permite que una clase cumpla con múltiples contratos y se adapte a múltiples roles simultáneamente.
Pruébalo tú mismo
import 'devices.dart';
void main() {
// TODO: Crea una Tablet con la marca 'Galaxy'
// TODO: Llama a connect()
// TODO: Llama a charge()
// TODO: Llama a showScreen('Welcome Home')
}
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 POO
Archivos externosLibrerías e importacionesIntroducción a la POOClases vs. ObjetosLa palabra clave thisMétodosVariables de instanciaConceptos básicos de constructoresResumen - Calculadora sencilla4Seguridad de nulos
Introducción a la seguridad de nulosNulables vs No nulablesLos operadores ? y !Palabra clave Late y Null SafetyOperadores Null-awareNull Safety en clasesResumen - Sistema de perfil de usuario7Clases abstractas e interfaces
Clases abstractasMétodos abstractosInterfaces en DartInterfaces implícitasImplementar vs. ExtenderInterfaces múltiplesRepaso - Calculadora de figuras10Colecciones y Genéricos
Visión general de List, Set y MapColecciones con seguridad de tiposClases genéricasMétodos genéricosRestricciones genéricasIterable e IteratorResumen - Almacenamiento genérico2Constructores en Dart
Constructor por defectoConstructores nombradosListas de inicializaciónConstructores constantesConstructores de fábricaConstructores de redireccionamientoResumen - Constructor de formas5Encapsulamiento
Miembros públicos vs. privadosLa convención del prefijo _Privacidad a nivel de libreríaProfundidad en Getters y SettersOcultamiento de informaciónResumen - Registros de estudiantes8Mixins
Introducción a los MixinsCreación de MixinsUso de múltiples MixinsPalabra clave on en MixinsMixin vs HerenciaMixin vs InterfazResumen - Sistema Animal11Métodos especiales
Sobrescritura de toString()Sobrescritura de hashCode y ==Interfaz ComparableMétodo call()Sobrescritura de noSuchMethodResumen - Colección personalizada14Patrones de diseño Parte 1
Introducción a los patrones de diseñoPatrón SingletonPatrón FactoryPatrón ObserverPatrón Strategy3Propiedades de clase
Miembros de instancia vs. estáticosCampos Final y ConstVariables LateMétodos y campos estáticosGetters y SettersResumen - Gestor de cuentas bancarias6Herencia
Herencia básicaLa palabra clave superSobrescritura de métodosLa anotación @overrideLa palabra clave final en clasesConstructores y herenciaResumen - Jerarquía de empleados9Polimorfismo
Fundamentos del polimorfismoPolimorfismo mediante interfacesComprobación de tipos en tiempo de ejecuciónLos operadores is y asPalabra clave covariantResumen - Procesador de pagos12POO Asíncrona
Futures y async/awaitFundamentos de StreamsStream ControllersConstructores asíncronosAsincronía en métodos de claseRepaso - Data Fetcher15Patrones de diseño Parte 2
Patrón CommandPatrón AdapterPatrón DecoratorPatrón Template MethodPatrón StatePatrón CompositePatrón Repository