Tabla de Contenido
0. Introducción1. 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).
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
5. Ejemplos
5.1 Simple
Archivo Figura.cs:
Archivo Circulo.cs:
Archivo Calculadora.cs:
Archivo CalculadoraEstandar.cs:
Archivo CalculadoraTrigonometrica.cs:
5.2 Calculadora
Figura 2. Herencia Calculadora. |
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
[1]: abstract (C# Reference) - http://msdn.microsoft.com/en-us/library/sf985hc5.aspx
[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
[4]: Abstract Classes - http://msdn.microsoft.com/en-us/library/k535acbf(v=vs.71).aspx
[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