lunes, 30 de diciembre de 2013

Clases y Miembros Abstractos en C#

Tabla de Contenido

0. Introducción
1. Clases y Miembros Abstractos en C#
1.1 Clases Abstractas
1.1.1 Definición
1.1.2 Restricciones
1.2 Miembros Abstractos
1.2.1 Definición
1.2.1.1 Métodos
1.2.1.2 Campos y Propiedades
1.2.2 Restricciones
2. Modificador abstract
3. Diferencias y Analogías entre Clases Abstractas e Interfaces
4. Rendimiento
5. Ejemplos
5.1 Simple
5.2 Calculadora
6. Conclusiones
7. Glosario
8. Enlaces & Literatura

0. Introducción

Paso en esta ocasión a escribir acerca de clases y miembros abstractos. Estos corresponden con representaciones abstractas (nivel de detalle generalizado) para miembros función y clases. Es decir, provee el mecanismo por el cual se puede definir clases, métodos, propiedades, indexadores, eventos con una implementación vacía dando cabida para que subtipos de la jerarquía, clases en particular, creen una definición a partir de un contrato abstracto y aprovechando la herencia, también, de miembros concretos. Ahora entramos en más detalles respecto a este concepto. Bienvenidos.

1. Clases y Miembros Abstractos en C#

Añadiendo a lo que mencioné al empezar con la introducción, en nuestro modelo del mundo del problema (o dominio del problema) podemos incluir conceptos de alto nivel conceptual y dejarlos preparados para definiciones específicas (i.e.: clases concretas, miembros función (i.e.: métodos, propiedades, indexadores, eventos). Además, nos permite aplicar conceptos de programación orientada a objetos, en especial polimorfismo [Polimorfismo en C#].

1.1 Clases Abstractas

Una clase abstracta se puede concebir como un elemento de dato que posee dos tipos de miembros:
  • Abstractos
  • Concretos
Con miembros abstractos me refiero a métodos, propiedades, &c., con ausencia de implementación. Y los miembros concretos son aquellos que proveen una implementación heredable por los tipos derivados. Además, pueden ser o no virtuales [Miembros Función Virtuales en C#].

1.1.1 Definición de una clase abstracta

Para definir una clase abstracta basta con incluir el modificador abstract (en la sección 2 hablaré con más detalle de este modificador) previo a la palabra clave class. Es como sigue:

abstract class MiClaseAbstracta
{
// miembros abstractos y concretos
}

1.1.2 Restricciones

A continuación una lista de las restricciones sobre clases abstractas más comunes:
  • Una clase abstracta no puede ser instanciada.
  • No es posible combinar la definición de una clase abstracta con el modificador sealed [Clases Estáticas en C#].
  • Una clase concreta que herede de una clase abstracta, deberá implementar cada uno de los métodos de esta última.

1.2 Miembros Abstractos

Una clase abstracta puede contener miembros abstractos (estamos hablando de indexadores, propiedades, métodos, y eventos).

1.2.1 Definición

Un miembro abstracto se define como una función capaz de poseer una la firma o contrato que ha de ser especializada por un subtipo de la jerarquía de herencia a partir de la clase abstracta (como superclase).

1.2.1.1 Métodos Abstractos

Un método abstracto consiste en la especificación de la firma en la declaración del método en cuestión. Esté deberá ser implementado por los tipos de datos heredados. Implícitamente un método abstracto es virtual (virtual) y deberá ser sobrescrito (override).

Ejemplo de un método abstracto:

public abstract double CalcularArea ();

Tenga en cuenta que el cuerpo del método ha sido reemplazada por un punto y coma (;). El compilador generará el siguiente error si especificamos (inclusive vacío) un cuerpo de implementación para el método abstracto:

error CS0500: `Tipo.CalcularArea()' cannot declare a body because it is marked abstract

La clase que herede de la clase abstracta que contiene el método anterior, debe seguir la siguiente regla de implementación del contrato:

public override double CalcularArea () 
// implementación del método abstracto
}

Se debe usar el modificador override para aceptar el contrato de la clase abstracta.

1.2.1.2 Campos y propiedades abstractas

Una propiedad abstracta que sea parte de un campo de clase puede declararse de la siguiente manera:

protected double numero;

public abstract double Numero
{
get;
set;
}

Una vez esta propiedad sea implementada por un tipo de dato heredado, quedará definida de la siguiente manera:

public override double Numero
{
get
{
return numero;
}
set
{
numero = value;
}
}

1.2.2 Restricciones

Restricciones más comunes de métodos y miembros abstractos:
  • Un método abstracto no puede ser de tipo private.
  • Un método abstracto no puede contener el modificador virtual.
  • Un miembro abstracto no puede ser marcado como static.

2. Modificador abstract

En la sección completa 1 se pudo apreciar el uso de la construcción léxica abstract. Es evidente que es el elemento léxico requerido para marcar una clase o un miembro como abstracto y que da la noción de carencia de implementación tanto en una clase o en un miembro.

3. Diferencias y Analogías entre Clases Abstractas e Interfaces

Esta es el conjunto de diferencias y analogías más comunes entre estos tipos de construcciones orientadas a objetos:
  • Una clase abstract puede contener tanto miembros concretos y abstractos. La interfaz únicamente abstractos (virtuales).
  • Una clase puede implementar una o más interfaces, mientras que sólo puede heredar de una única clase abstracta.
  • Tanto de una clase como una interfaz no se pueden crear instancias.
  • Los miembros abstractos, tanto de una intefaz como de una clase abstracta, deben ser implementados en el tipo heredado.
  • Una clase abstract puede intentar parecerse a una interfaz cuando todos sus miembros son de tipo virtual.

3.1 Decisión de Diseño

Vale la pena tener en cuenta la recomendación de selección hecha en [5] por Jayabu [6]:
"The selection of interface or abstract class depends on the need and design of your project. You can make an abstract class, interface or combination of both depending on your needs."

4. Rendimiento

Diríjase a [7] para ver con detalle la prueba hecha por Sam Allen [8] para diferenciar los detalles de rendimiento entre implementación (uso de interfaces) y herencia (uso de clases abstractas).

Sin embargo, quiero, hacer la prueba usando el código fuente expuesto en [7]:
Prueba de rendimiento entre interfaces y clases abstractas.
Figura 1. Prueba de rendimiento entre interfaces y clases abstractas.

Datos estadísticos generales de la prueba:



Máximo:
Interfaz: 12.26
Clase: 4.20

Mínimo
Interfaz: 4.34
Clase: 4.20

Media:
Interfaz: 7.57
Clase: 6.08

Desviación estándar:
Interfaz: 4.16
Clase: 2.76


Hardware de pruebas: CPU, Memoria.

5. Ejemplos

5.1 Simple

Archivo Figura.cs:
Archivo Circulo.cs:

5.2 Calculadora
Herencia Calculadora.
Figura 2. Herencia Calculadora.

Archivo Calculadora.cs:

Archivo CalculadoraEstandar.cs:

Archivo CalculadoraTrigonometrica.cs:

[Nota: Omito las pruebas en Ideone por resultar evidente los resultados de las operaciones. Lo que nos interesa en realidad es observar la utilidad de las clases abstractas en una jerarquía de herencia.]

Conclusiones

El trabajo en este artículo ha caído en la comprensión del concepto de abstracto en programación orientada objetos, más precisamente en su uso en el lenguaje de programación C#. Vimos que una clase abstracta es un intermedio entre una clase concreta y una interfaz, pues posee características inherentes a cada una de ellas. La prueba de rendimiento en la sección 4 nos llevo a la conclusión que el uso de clases abstractos recae en un mejor rendimiento (vale aclarar que estas pruebas se realizaron en una sola máquina). Al final escribí unos ejemplos sencillos para apreciar las ventajas de diseño de uso de clases abstractas, en particular en la jerarquía de herencia de Calculadora.

Glosario

- Abstract
- Abstracto
- Clase
- Concreto
- Miembro

Enlaces & Literatura

[2]: C# Abstract Keyword - http://www.dotnetperls.com/abstract
[3]: Understanding C# Abstract Classes - Techotopia - http://www.techotopia.com/index.php/Understanding_C_Sharp_Abstract_Classes
[5]: All about abstract classes. - CodeProject - http://www.codeproject.com/Articles/6118/All-about-abstract-classes
[6]: Jayababu - Professional Profile - CodeProject - http://www.codeproject.com/Members/Jayababu
[7]: C# Interface Versus Virtual Method Performance - http://www.dotnetperls.com/interface-virtual-performance
[8]: About: Sam Allen - http://www.dotnetperls.com/about


H

No hay comentarios:

Publicar un comentario

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