martes, 6 de mayo de 2014

Interfaces en C# - Parte 5

Tabla de Contenido

0. Introducción
1. Reimplementar Miembros de una Interfaz en una Subclase
1.1 Ejemplo abstracto: implementación explícita de una interfaz por una subclase
1.2 Ejemplo abstracto: implementación implícita de una interfaz por una subclase
2. Ejemplo Concreto de Reimplementación de Miembros de una Interfaz
3. Notas Importantes
4. Conclusiones
5. Glosario
6. Enlaces & Literatura

0. Introducción

En la parte 4 de la serie de Interfaces en C# vimos que es posible redefinir un método abstracto en una clase que implemente a su interfaz. Lo que ahora vamos a aprender, consiste en llevar a cabo esa redefinición en los subtipos que hereden de una superclase (y que ésta haya implementado la interfaz) a través de la construcción (modificador) new. Los ejemplos abstractos y concretos que se presentarán nos ilustrarán este cometido en C#.

Resumen de los temas cubiertos hasta el momento en la serie de artículos acerca de interfaces:

1. Reimplementar Miembros de una Interfaz en una Subclase

En el artículo anterior -Interfaces en C# - Parte 4- vimos que en C# es posible reimplementar un método abstracto a través del modificar virtual, el cual facilita la sobreescritura de este nuevo método en subclases que hereden de la superclase. C#, además, permite redefinir los miembros de la interfaz en una subclase a través del modificador new [2].

Para lograr lo anterior, la subclase debe implementar la interfaz, heredar de una superclase que haya implementado esa misma interfaz, luego en su cuerpo de declaración de miembros especificar con el modificador new el método de interfaz a reimplementar.

Vale aclarar que esta reemplimentación es independiente de si la superclase ha implementado explícita o implícitamente los métodos abstractos de la interfaz. E inclusive, ignora si en la superclase hemos redefinido el método abstracto con el modificador virtual. El único requisito como ya mencionamos, es que tanto la superclase y la subclase implementen una misma interfaz.

1.1 Ejemplo abstracto: implementación explícita de una interfaz por una superclase

Veamos como llevamos a cabo este proceso de reimplementación de métodos abstractos en subclases.

Primero definamos una interfaz:

public interface Interfaz
{
void Metodo();
}

Ahora definamos una clase que implemente esta interfaz:

public class Superclase : Interfaz
{
  void Interfaz.Metodo() // implementación explícita del método de la interfaz
{
Console.WriteLine("Invocación de Método en Superclase.");
}
}

Creemos la definición de una subclase de la clase previa, y además reemplimentemos el método Metodo:

public class Subclase : Superclase, Interfaz
{
public new void Metodo()
{
Console.WriteLine("Invocación de Método en Subclase.");
}
}


Ya con el modificador new en la firma del método Metodo contamos con una nueva implementación. Ahora, ¿cómo podemos invocar la nueva implementación desde código cliente? Así:


public static void Main()
{
Subclase sc = new Subclase();
sc.Metodo(); // Salida 1: Invocación en Método en Subclase
((Interfaz)sc).Metodo(); // Salida 2: Invocación en Método en Subclase
}

> Prueba de ejecución.

1.2 Ejemplo abstracto: implementación implícita de una interfaz por una superclase

¿Y qué tal si la clase Superclase hubiese implementado de forma implícita los miembros de la interfaz Interfaz? De esta manera:

public class Superclase : Interfaz
{
public void Metodo()
{
Console.WriteLine("Invocación de Método en Superclase.")
}
}


[Nota: Omito la definición de la subclase porque es exactamente igual a la anterior (a la de la sección 1.14).]



En código cliente, podemos, a través de la conversión explícita al subtipo la llamada al método Metodo de esa esa misma clase:


public static void Main()
{
Subclase sc = new Subclase();
sc.Metodo(); // Salida 1: Invocación en Método en Subclase
((Interfaz)sc).Metodo(); // Salida 2: Invocación en Método en Subclase
((Superclase)sc).Metodo(); // Salida 3: Invocación en Método en Superclase
}


Con el resultado ((Superclase)sc).Metodo() queda demostrado que la reimplimentación de miembros de una interfaz en subclases es más apropiado cuando éstos son implementados explícitamente en una superclase.

> Prueba de ejecución.

2. Ejemplo Concreto de Reimplimentación de Miembros de Interfaz

Tenemos la siguiente interfaz:

public interface IDeshacible
{
void Deshacer();
}

Implementación de forma explícita sobre la clase CampoTexto:

public class CampoTexto : IDeshacible
{
public void Deshacer()
{
Console.WriteLine("Invocación de Deshacer en CampoTexto.");
}
}

Ahora creamos la clase para un control más completo:

public class CampoTextoEnriquecido : CampoTexto, IDeshacible
{
public new void Deshacer()
{
Console.WriteLine("Invocación de Método en CampoTextoEnriquecido.");
}
}

Desde código cliente podríamos invocar la nueva implementación sobre CampoTextoEnriquecido:

public static void Main()
{
CampoTextoEnriquecido cte = new CampoTextoEnriquecido();
cte.Deshacer();
((IDeshacible)cte).Deshacer();
}


En la Figura 1 se muestra la jerarquía de implementación y de herencia.
Reimplementación de miembros de interfaz
Figura 1. Reimplementación de miembros de interfaz.

3. Notas Importantes

Desde [1] apuntan estas consideraciones acerca de las situaciones problemáticas de la implementación explícita de miembros de interfaz:
Problemas comunes en la reemplimentación de interfaces
Figura 2. Problemas comunes en la reemplimentación de interfaces.
También sugieren que la reimplementación de interfaces se utiliza como último recurso cuando no ha previsto un diseño extendido (herencia) de los tipos del modelo del mundo del problema.

4. Conclusiones

Hemos aprendido que es posible reimplementar un método abstracto de una interfaz en una subclase a través del uso del modificador new. En los ejemplos entendimos que la implementación explícita es más coherente y mantiene la semántica entre tipos en una jerarquía implementación y de herencia.

5. Glosario

  • Clase
  • Interfaz
  • Jerarquía herencia
  • Jerarquía implementación
  • Subclase
  • Superclase

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]: new Modifier (C# Reference) - http://msdn.microsoft.com/en-us/library/435f1dw2.aspx
[3]: Interfaces en C# - Parte 1 | OrtizOL - Experiencias Construcción Software (xCSw) - http://ortizol.blogspot.com/2014/05/interfaces-en-c-parte-1.html
[4]: Interfaces en C# - Parte 2 | OrtizOL - Experiencias Construcción Software (xCSw) - http://ortizol.blogspot.com/2014/05/interfaces-en-c-parte-2.html
[5]: Interfaces en C# - Parte 3 | OrtizOL - Experiencias Construcción Software (xCSw) - http://ortizol.blogspot.com/2014/05/interfaces-en-c-parte-3.html
[6]: Interfaces en C# - Parte 4 | OrtizOL - Experiencias Construcción Software (xCSw) - http://ortizol.blogspot.com/2014/05/interfaces-en-c-parte-4.html


J

No hay comentarios:

Publicar un comentario

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