domingo, 4 de mayo de 2014

Interfaces en C# - Parte 1

Tabla de Contenido

0. Introducción
1. ¿Qué es una Interfaz?
2. La Palabra Clave interface en C#
3. Interfaces de Ejemplo en C#
3.1 Casos en la declaración e implementación de una interfaz
3.2 Ejemplo Básico: IRadio
3.3 Interfaz IEnumerator en el Framework .NET
4. Conclusiones
5. Glosario
6. Enlaces & Literatura

0. Introducción

En esta ocasión va a aprender acerca de otras las construcciones de la programación orientada a objetos en C#: las interfaces. Las interfaces es uno de los mecanismos con los que podemos crear una jerarquía de herencia basada en contratos. Veremos que los contratos no son más que las especificaciones de funciones (métodos, eventos, indexers, propiedades) que deben ser implementadas por las clases o structs que implementen la clase. Entenderemos su porqué y su utilidad a través de casos prácticos. En esta primera parte nos concentraremos en la naturaleza de las interfaces.

1. ¿Qué es una interfaz?

Podemos definir a una interfaz como un contrato en donde se especifican todas los términos y especificaciones (funciones: métodos, propiedades, eventos, e indexers) que se deben cumplir para realizar y concretar el contrato. En términos de los lenguajes de programación, en particular C#, una interfaz define funciones abstractas, esto quiere decir que no poseen implementación.

Continuando, una clase abstracta -cfr. Clases y Miembros Abstractos en C#- posee miembros concretos (con implementación) y miembros abstractos (sin implementación). En esta última parte es que se parecen las interfaces con las clases abstractAs. Las interfaces sólo contienen funciones (miembros) abstractos. A esto podemos apuntar que todos los miembros de una interfaz son implícitamente abstractos. Inclusive, podemos agregar que en una clase puede implementar n cantidad de interfaces, igualmente los structs -cfr. Structs en C#-.


Por otro lado, las interfaces son la construcción que se encarga de disolver la ambigüedad producida por la herencia múltiple de clases. Sabemos que la herencia múltiple no está permitida en C#. En [5] podemos encontrar la descripción del problema del diamente. Este problema es una de las razones que justifica la omisión de la herencia múltiple en la mayoría de los lenguajes de programación modernos (y C# no es la excepción).
Problema del diamente
Figura 1. Problema del diamante [5].
[Nota: Para comprender el problema del diamante recomiendo la lectura de la sección en [5] 'The diamond problem'.]


Evidentemente, para mitigar este problema: sólo es posible practicar la herencia simple. Empero, las interfaces a través de sus contratos pueden crear el efecto de herencia múltiple. Para ilustrar este concepto, veamos la Figura 2.
Herencia e implementación de interfaces
Figura 2. Herencia e implementación de interfaces.
Obsérvese cómo la clase Subclase hereda de la clase Superclase, también implementa las interfaces Interfaz1, e Interfaz2; por lo tanto podemos decir que hay una relación de es-un en esta jerarquía de herencia. Así:
  • Subclase es-un Interfaz1
  • Subclase es-un Interfaz2
  • Subclase es-un Superclase

2. La Palabra Clave interface en C#

La construcción sintáctica para declarar interfaces en C# es interface. Aquí el uso general de declaración:

{modificador de acceso} interface {Nombre de la Interfaz}

Pongamos por caso:

public interface IRadio

En cuanto a los miembros, se declaran así:

Métodos:
[public] {tipo de retorno} {nombre del método}([parámetros]);

Propiedades:
[public] {tipo de retorno} {nombre de la propiedad}
{
get;
set;
}

Indexers [8]:
[public] this[{tipo índice} {identificador del índice}]
{
get;
set;
}

Eventos:
[public] event {tipo evento} {nombre del evento};

Una interfaz completa:

public interface IRadio
{
void Sintonizar(Frecuencia f);
void Apagar();
void Encender();
void CambiarModulacion(Modulacion m);
}

3. Ejemplos de Interfaces en C#

3.1 Casos en la declaración e implementación de una interfaz

3.1.1 Caso elemental

Aquí vamos a observar que la declaración de una clase y una interfaz funcionan como se espera:

internal class Clase
{
public static void Main()
{
Console.WriteLine("Ejemplo de interfaces");
}
}

interface Interfaz
{
}

Ejecución:


Ejemplo de interfaces

3.1.2 Campos en una interfaz

internal class Clase
{
public static void Main()
{
Console.WriteLine("Ejemplo de interfaces");
}
}

interface Interfaz
{
int x;
}

Resultado de ejecución:


error CS0525: Interfaces cannot contain fields or constants


El error CS0525 [10] indica que una interfaz no puede contener campos o constantes.

3.1.3 Métodos en una interfaz

internal class Clase
{
public static void Main()
{
Console.WriteLine("Ejemplo de interfaces");
}
}

interface Interfaz
{
void Metodo()
{
Console.WriteLine("Método concreto en interfaz");
}
}

Resultado de ejecución:


error CS0531: `Interfaz.Metodo()': interface members cannot have a definition

El error CS0531 [11] nos indica que los métodos no pueden contender una implementación.

3.1.4 Omisión de la implementación de miembros en una clases concreta

internal class Clase : Interfaz
{
public static void Main()
{
Console.WriteLine("Ejemplo de interfaces");
}
}

interface Interfaz
{
void Metodo();
}

Resultado de ejecución:


error CS0535: `Clase' does not implement interface member `Interfaz.Metodo()'


El compilador generará el error CS0535 [12] que indica que la clase Clase no ha implementado el miembro (método) de la interfaz Interfaz.

3.1.5 Implementación correcta de la interfaz Interfaz

internal class Clase : Interfaz
{
public static void Main()
{
Console.WriteLine("Ejemplo de interfaces");
}

public void Metodo()
{
Console.WriteLine("Método Metodo implementado.");
}
}

interface Interfaz
{
void Metodo();
}


En este último caso, la compilación es satisfactoria.

3.2 Ejemplo básico: IRadio

public interface IRadio
{
void Sintonizar(Frecuencia f);
void Apagar();
void Encender();
}

Implementación:


public class WebRadio: IRadio
{
 private Frecuencia freq;
 private bool estado;

 public void Sintonizar(Frecuencia f)
{
freq = f;
}

public void Apagar()
{
estado = !estado;
}

void Encender()
{
estado = !estado;
}
}

3.3 La interfaz IEnumerator en el Framework .NET

En el nombre de espacio (namespace) System.Collections encontramos la interfaz IEnumerator [9], la cual tiene el siguiente conjunto de miembros:

public interface IEnumerator
{
bool MoveNext();
object Current { get; }
void Reset();
}

Observemos que a pesar de que hayamos omitido la especificación de public en cada declaración de miembros, éstos son implícitamente public.

Ahora implementemos esta clase:

internal class CuentaRegresiva : IEnumerator
{
int contador = 10;

public bool MoveNext()
{
return contador-- > 0;
}

public object Current
{
get
{
return contador;
}
}

public void Reset()
{
contador = 10;
}
}

4. Conclusiones

En esta primera parte hemos estudiado las interfaces atendiendo los conceptos básicos, la construcción para declarar interfaces -interface. También se introdujo la relacion entre clases, structs, e interfaces. Se demostró cómo crear funciones. métodos, eventos, indexers, y propiedades. Al final tres ejemplos para demostrar el uso de interfaces en donde comprendimos los errores comunes en la declaración e implementación de interfaces. En la siguiente parte, vamos a trabajar con la extensión de interfaces.

5. Glosario

  • Contrato
  • Evento
  • Implementación
  • Interfaz
  • interface
  • Método
  • Propiedad

6. Enlaces & Literatura

[1]: C# 5.0 in a Nutshell by Joseph Albahari and Ben Albahari. Copyright 2012 Joseph Albahari and Ben Albahari, 978-1-449-32010-2.
[2]: Lesson 13 - Interfaces - http://www.csharp-station.com/Tutorial/CSharp/Lesson13
[3]: Interfaces in C# (For Beginners) - http://www.codeproject.com/Articles/18743/Interfaces-in-C-For-Beginners
[4]: Clases y Miembros Abstractos en C# | OrtizOL - Experiencias Construcción Software (xCSw) - http://ortizol.blogspot.com/2013/12/clases-y-miembros-abstractos-en-c.html
[5]: Multiple inheritance, the free encyclopedia - https://en.wikipedia.org/wiki/Multiple_inheritance
[6]: Structs en C# | OrtizOL - Experiencias Construcción Software (xCSw) - http://ortizol.blogspot.com/2014/04/structs-en-c.html
[7]: interface (C# Reference) - http://msdn.microsoft.com/en-us/library/vstudio/87d83y5b%28v=vs.100%29.aspx
[8]: Indexers in Interfaces (C# Programming Guide) - http://msdn.microsoft.com/en-us/library/tkyhsw31.aspx
[9]: IEnumerator Interface (System.Collections) - http://msdn.microsoft.com/en-us/library/system.collections.ienumerator%28v=vs.110%29.aspx
[10]: Compiler Error CS0525 - http://msdn.microsoft.com/en-us/library/abebybz6%28v=vs.90%29.aspx
[11]: Compiler Error CS0531 - http://msdn.microsoft.com/en-us/library/9w9tw635%28v=vs.90%29.aspx
[12]: Compiler Error CS0535 - http://msdn.microsoft.com/en-us/library/525wxbha%28v=vs.90%29.aspx


J

No hay comentarios:

Publicar un comentario

Envíe sus comentarios, dudas, sugerencias, críticas. Gracias.