Interfaces Múltiples
Parte de la sección Programación Orientada a Objetos del Journey de C# de Coddy. Lección 27 de 70.
Aunque una clase solo puede heredar de una clase base, puede implementar tantas interfaces como necesite. Esta es una de las ventajas clave que tienen las interfaces sobre las clases abstractas: permiten que una clase adopte múltiples comportamientos.
Para implementar varias interfaces, simplemente enuméralas después de los dos puntos, separadas por comas:
public interface IFlyable
{
void Fly();
}
public interface ISwimmable
{
void Swim();
}
public class Duck : IFlyable, ISwimmable
{
public void Fly()
{
Console.WriteLine("Flying through the air");
}
public void Swim()
{
Console.WriteLine("Swimming in the pond");
}
}La clase Duck debe implementar todos los miembros de ambas interfaces. Esto modela de forma natural los escenarios del mundo real: un pato realmente puede volar y nadar, por lo que tiene sentido que cumpla ambos contratos.
Al combinar la herencia con múltiples interfaces, la clase base debe ir primero:
public class Duck : Bird, IFlyable, ISwimmable
{
// Hereda de Bird, implementa ambas interfaces
}Esta flexibilidad te permite combinar comportamientos de múltiples fuentes. Un Robot podría implementar IMovable, IChargeable y ISpeakable. Cada interfaz representa una única capacidad, y tu clase puede combinar exactamente lo que necesita.
Desafío
FácilConstruyamos un sistema de dispositivos para un hogar inteligente que demuestre cómo una sola clase puede implementar varias interfaces para adquirir distintas capacidades. Crearás dispositivos que puedan controlarse y que también tengan funciones de administración de energía.
Organizarás tu código en cuatro archivos:
IControllable.cs: Define una interfaz llamadaIControllableen el espacio de nombresSmartHome. Esta interfaz representa dispositivos que pueden encenderse y apagarse. Debe declarar dos métodos:TurnOn()yTurnOff(), ambos con un valor de retorno de tipo string.INetworkConnected.cs: Define una interfaz llamadaINetworkConnecteden el espacio de nombresSmartHome. Esta interfaz representa dispositivos que pueden conectarse a una red. Debe declarar un métodoConnect(string network)que devuelva un string.SmartTV.cs: Define una claseSmartTVen el espacio de nombresSmartHomeque implemente tantoIControllablecomoINetworkConnected. El televisor debe tener una propiedadBrand(string) y una propiedadScreenSize(int, que representa pulgadas). Crea un constructor que acepte ambos valores. Implementa todos los métodos de las interfaces:TurnOn()devuelve"{Brand} {ScreenSize}-inch TV is now ON"TurnOff()devuelve"{Brand} {ScreenSize}-inch TV is now OFF"Connect(string network)devuelve"{Brand} TV connected to {network}"
Program.cs: En tu archivo principal, crea unSmartTVusando los valores de entrada. Demuestra la flexibilidad de las interfaces múltiples almacenando el mismo objeto de tipo TV en tres tipos de variables diferentes: el tipo concretoSmartTV, una variableIControllabley una variableINetworkConnected. Llama a los métodos apropiados mediante cada referencia para mostrar cómo se puede tratar el mismo objeto de manera diferente según la interfaz con la que estés trabajando.
Recibirás tres entradas:
- Nombre de la marca del televisor
- Tamaño de la pantalla en pulgadas
- Nombre de la red a la que conectarse
Imprime la salida con este formato:
Via SmartTV:
{TurnOn() result}
{Connect(network) result}
Via IControllable:
{TurnOff() result}
Via INetworkConnected:
{Connect(network) result}Por ejemplo, si las entradas son Samsung, 55 y HomeWiFi, la salida debería ser:
Via SmartTV:
Samsung 55-inch TV is now ON
Samsung TV connected to HomeWiFi
Via IControllable:
Samsung 55-inch TV is now OFF
Via INetworkConnected:
Samsung TV connected to HomeWiFiObserva cómo se puede acceder al mismo objeto SmartTV mediante distintas referencias a interfaces. Cuando se almacena como IControllable, solo puedes llamar a métodos de control. Cuando se almacena como INetworkConnected, solo puedes llamar a métodos de red. ¡Este es el poder de implementar varias interfaces: una clase adquiere múltiples capacidades y, al mismo tiempo, mantiene flexibilidad en la forma en que se utiliza!
Pruébalo tú mismo
using System;
using SmartHome;
class Program
{
public static void Main(string[] args)
{
// Leer entradas
string brand = Console.ReadLine();
int screenSize = Convert.ToInt32(Console.ReadLine());
string network = Console.ReadLine();
// TODO: Crea un objeto SmartTV con los valores de entrada
// TODO: Almacena el mismo objeto TV en tres tipos de variables diferentes:
// 1. Tipo SmartTV (clase concreta)
// 2. IControllable type (interface reference)
// 3. INetworkConnected type (interface reference)
// TODO: Imprime la salida en el formato requerido:
// Via SmartTV:
// - Llama a TurnOn() y Connect(network)
// Via IControllable:
// - Llama a TurnOff()
// Via INetworkConnected:
// - Llama a Connect(network)
}
}
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 externosNamespaces y directivasIntro a clases y objetosLa palabra clave 'this'Métodos y parámetrosCampos vs PropiedadesConstructoresInicializadores de objetosResumen - Calculadora simple4Herencia
Sintaxis básica de herencia (:)La palabra clave 'base'Palabras clave Virtual y OverrideClases selladas (Sealed)La clase base 'object'Resumen: Jerarquía de empleados7Características avanzadas
Sobrecarga de operadoresIndexadores (this[])Sobrescritura de ToString()Métodos de extensiónResumen - Lista personalizada10Patrones de diseño - Parte 1
Introducción a los patrones de diseñoSingleton Thread-SafePatrón FactoryPatrón Observer (Eventos)Patrón Strategy2Propiedades y miembros estáticos
Propiedades autoimplementadasPropiedades de solo lectura y escrituraCampos y métodos estáticosClases estáticasMiembros con cuerpo de expresión5Polimorfismo e Interfaces
Polimorfismo: Compilación vs. EjecuciónInterfaz vs. Clase AbstractaInterfaces MúltiplesInterfaces ExplícitasUpcasting y DowncastingRepaso: Calculadora de Figuras8Conceptos avanzados de POO
Composición sobre herenciaGenéricos (clases y métodos)Delegados y eventosAtributos y ReflexiónIDisposable y la sentencia usingFundamentos de Inyección de dependencias11Patrones de diseño, parte 2
Patrón CommandPatrón AdapterPatrón DecoratorPatrón Template MethodPatrón StatePatrón Composite3Arquitectura de clases
Datos de instancia vs. estáticosPalabras clave 'readonly' y 'const'Campos de respaldoResumen - Gestor de cuentas bancarias6Encapsulamiento
Modificadores de accesoPropiedades para el encapsulamientoImplementación de ocultamiento de datosPatrones de inmutabilidadRepaso - Registros de estudiantesPractica por tu cuenta: Compilador de C# online