csharp-interfaces

Qué son y cómo usar los interface en C#

Un interfaz en es una colección de definiciones de métodos, propiedades, eventos o indexadores que una clase o una estructura puede implementar.

A diferencia de las clases, los interfaces no contienen implementaciones de métodos (solo definen los miembros que deben ser implementados por las clases o estructuras que los implementan).

Las interfaces son fundamentales en la programación orientada a objetos porque permiten definir funcionalidades y comportamiento que pueden ser implementadas por diferentes clases, favoreciendo la mantenibilidad y la reutilización del código.

Interfaces en C#

La declaración de una interfaz se realiza utilizando la palabra clave interface.

[modificador] interface NombreDeLaInterfaz
{
    // Definición de métodos
    tipoDeDato NombreDelMetodo(parametros);

    // Definición de propiedades
    tipoDeDato NombreDeLaPropiedad { get; set; }
}
  • NombreDeLaInterfaz: Es el nombre único que se le da a la interfaz.
  • Modificador: Puede ser public o internal para definir el nivel de acceso de la interfaz.
  • tipoDeDato: Especifica el tipo de datos de las propiedades y métodos.
  • NombreDelMetodo, NombreDeLaPropiedad: Son los identificadores únicos de los métodos, propiedades y eventos respectivamente.
  • parametros: Son las variables que se utilizan para pasar información al método cuando se llama.

Implementación de Interfaces

Para implementar un interfaz en una clase, se utiliza la sintaxis de dos puntos (:) seguida del nombre del interfaz. La clase debe proporcionar implementaciones para todos los miembros definidos en el interfaz.

Aquí hay un ejemplo de cómo definir e implementar una interfaz en C#:

public interface IConducible
{
    string Matricula { get; set; }

    // Métodos
    void Conducir();
    void Frenar();
}

public class Coche : IConducible
{
    // Implementación de propiedades    
    public string Matricula { get; set; }

    // Implementación de métodos
    public void Conducir()
    {
        Console.WriteLine("El coche está en marcha.");
    }

    public void Frenar()
    {
        Console.WriteLine("El coche se ha detenido.");
    }
}

En este ejemplo:

  • Se define una interfaz IVehiculo con una propiedad (Matricula) y dos métodos (Conducir y Frenar).
  • La clase Coche implementa la interfaz IVehiculo y proporciona la implementación de todas sus propiedades y métodos.

Polimorfismo con interfaces

Una de las características más importantes de los interfaces es su capacidad para soportar el polimorfismo. Esto permite que una instancia de una clase que implementa un interfaz sea tratada como una instancia de ese interfaz.

Supongamos que tengamos otra clase que implementa IConducible llamara Bicicleta

public class Bicicleta : IConducible
{
	// implementación
}

Ahora podemos definir una variable de tipo IConducible, y asignar variables de tipo Coche o Bicicleta.

IConducible vehiculo;

vehiculo = new Coche();
vehiculo.Arrancar(); // Salida: El coche ha arrancado.
vehiculo.Detener();  // Salida: El coche se ha detenido.

vehiculo = new Bicicleta();
vehiculo.Arrancar(); // Salida: La bicicleta ha comenzado a moverse.
vehiculo.Detener();  // Salida: La bicicleta se ha detenido.

Implementar múltiples interfaces

C# no soporta la herencia múltiple directa (una clase derivada de múltiples clases base). Sin embargo, una clase puede implementar múltiples interfaces, lo que proporciona una forma de lograr un comportamientos similar a la herencia múltiple.

Por ejemplo, en este ejemplo, la clase Pato implementa los interfaces IVolador e INadador.

public interface IVolador
{
    void Volar();
}

public interface INadador
{
    void Nadar();
}

public class Pato : IVolador, INadador
{
    public void Volar()
    {
        Console.WriteLine("El pato está volando.");
    }

    public void Nadar()
    {
        Console.WriteLine("El pato está nadando.");
    }
}

Implementación explícita

C# permite la implementación explícita de miembros de interfaces. Esto es útil cuando una clase implementa múltiples interfaces que pueden tener métodos con el mismo nombre, o cuando se desea proporcionar implementaciones específicas que no sean accesibles directamente a través de la clase.

En este ejemplo, la clase Multifuncional implementa los interfaces IImprimible e IEscaneable. Pero ambos interface declaran un método Imprimir(). Podemos declarar explícitamente los interfaces para resolver el conflicto de nombres.

public interface IImprimible
{
    void Imprimir();
}

public interface IEscaneable
{
    void Imprimir();
}

public class Multifuncional : IImprimible, IEscaneable
{
    void IImprimible.Imprimir()
    {
        Console.WriteLine("Imprimiendo...");
    }

    void IEscaneable.Imprimir()
    {
        Console.WriteLine("Escaneando...");
    }
}

// Uso
IImprimible impresora = new Multifuncional();
impresora.Imprimir(); // Salida: Imprimiendo...

IEscaneable escaner = new Multifuncional();
escaner.Imprimir(); // Salida: Escaneando...

Ejemplos prácticos

Representación de un dispositivo electrónico

Esta interfaz IEncendible define los métodos que un dispositivo electrónico debe tener. La clase Telefono implementa esta interfaz:

public interface IEncendible
{
    // Métodos
    void Encender();
    void Apagar();
    void Reiniciar();
}

public class Telefono : IEncendible
{
    // Implementación de métodos
    public void Encender()
    {
        Console.WriteLine("El teléfono se está encendiendo.");
    }

    public void Apagar()
    {
        Console.WriteLine("El teléfono se está apagando.");
    }

    public void Reiniciar()
    {
        Console.WriteLine("El teléfono se está reiniciando.");
    }
}

Comportamiento de Comunicación

Esta interfaz IComunicador define los métodos que un dispositivo de comunicación debe tener. La clase Telefono implementa esta interfaz, mientras que mantiene IEndendible

public interface IComunicador
{
    // Métodos
    void Llamar(string numero);
    void EnviarMensaje(string numero, string mensaje);
}

public class Telefono : IComunicador, IEncendible
{
	// ... codigo de IEncendible del ejemplo anterior ... //
	
    // Implementación de métodos IComunicador
    public void Llamar(string numero)
    {
        Console.WriteLine($"Llamando al número {numero}.");
    }

    public void EnviarMensaje(string numero, string mensaje)
    {
        Console.WriteLine($"Enviando mensaje al número {numero}: {mensaje}");
    }
}

Comportamiento de Pagos

Esta interfaz IPagos define los métodos que un sistema de pagos debe tener. La clase PagoElectronico implementa esta interfaz:

public interface IPagos
{
    // Métodos
    void ProcesarPago(decimal monto);
    void ReembolsarPago(decimal monto);
}

public class PagoElectronico : IPagos
{
    // Implementación de métodos
    public void ProcesarPago(decimal monto)
    {
        Console.WriteLine($"Procesando pago de {monto}.");
    }

    public void ReembolsarPago(decimal monto)
    {
        Console.WriteLine($"Reembolsando pago de {monto}.");
    }
}