Módulo 02: POO Avanzada en Dart

Interfaces Implicitas

Sistema Clases

# Interfaces Implícitas en Dart A diferencia de Java o C#, Dart no tiene una palabra clave `interface`. En su lugar, **cada clase define implícitamente una interfaz** que contiene todos sus miembros públicos. ## ¿Cómo funcionan? Cualquier clase puede actuar como una interfaz si la implementas usando la palabra clave `implements`. ```dart // Una clase normal class Person { final String name; Person(this.name); void greet() { print('Hello, I am $name'); } } // Implementando la interfaz implícita de Person class Impostor implements Person { // ⚠️ Debemos implementar TODOS los miembros públicos @override String get name => 'Unknown'; @override void greet() { print('I am not who you think I am'); } } ``` ## Clases Abstractas como Interfaces Es común definir clases abstractas puras (sin implementación) para usarlas explícitamente como interfaces. ```dart // Definición de Interfaz (convención: usar clase abstracta) abstract class Flyable { void fly(); double get altitude; } abstract class Swimmable { void swim(); } // Implementación Múltiple class Duck implements Flyable, Swimmable { @override double altitude = 0; @override void fly() { print('Duck flying'); altitude += 10; } @override void swim() { print('Duck swimming'); } } ``` ## `extends` vs `implements` ### `extends` (Herencia) - Comparte comportamiento e implementación. - Relación "es un" fuerte. - Solo una superclase. - Heredas el código de la clase padre. ### `implements` (Interfaz) - Comparte solo la firma (API). - Relación "se comporta como". - Múltiples interfaces. - Debes escribir tu propia implementación de todo. ```dart class Engine { void start() => print('Engine started'); } // Herencia: Car TIENE el código de start() class Car extends Engine {} // Interfaz: SmartCar DEBE implementar start() class SmartCar implements Engine { @override void start() { print('Smart engine booting sequence...'); } } ``` ## Casos de Uso en Flutter ### 1. Mocking en Tests Las interfaces implícitas hacen que el mocking sea trivial en Dart. Puedes crear un mock de *cualquier* clase implementándola. ```dart class ApiService { Future fetchData() async { // Llamada real a red compleja return 'Real Data'; } } // En tus tests class MockApiService implements ApiService { @override Future fetchData() async { return 'Test Data'; } } void main() { test('should use mock data', () async { final api = MockApiService(); // Polimorfismo expect(await api.fetchData(), 'Test Data'); }); } ``` ### 2. Protocolos de Delegación Similar a iOS, puedes definir interfaces para delegar acciones. ```dart abstract class SelectionListener { void onItemSelected(String item); } class ListWidget { final SelectionListener listener; ListWidget(this.listener); void tapItem(String item) { listener.onItemSelected(item); } } ``` ## Combinando Interfaces Puedes implementar múltiples interfaces para crear objetos con capacidades compuestas. ```dart abstract class JSONSerializable { Map toJson(); } abstract class Copyable { T copy(); } class User implements JSONSerializable, Copyable { final String name; User(this.name); @override Map toJson() => {'name': name}; @override User copy() => User(name); } ``` ## Conclusión El sistema de interfaces implícitas de Dart es poderoso y flexible. - No necesitas declarar `interface MyInterface`. - Usa `abstract class` para definir contratos. - Usa `implements` para cumplir contratos. - Usa `implements` para mocks y tests.

Este apartado profundiza en los conceptos clave, proporcionando ejemplos prácticos y mejores prácticas para su aplicación en proyectos reales.

Al comprender estos detalles, podrás diseñar soluciones más robustas, mantenibles y escalables en tus aplicaciones Flutter y Dart.