domingo, 15 de diciembre de 2013

Polimorfismo en C#

Tabla de Contenido

0. Introducción
1. Polimorismo
1.1 Concepto de Polimorfismo
1.2 Tipos de Polimorfismo
1.2 Subtipado
2. Polimorfismo en C#
3. Aspectos Intrínsecos con Polimorfismo en C#
3.1 Polimorfismo Estático o de Tiempo de Compilación
3.2 Polimorfismo Dinámico o de Tiempo de Ejecución
4. Polimorfismo con Interfaces
5. Conclusiones
6. Glosario
7. Enlaces & Literatura

0. Introducción

Otro de los pilares fundamentales de la programación orientada a objetos es el polimorfismo. El concepto base sobre este pilar consiste en atribuir a un objeto múltiples formas. Y en consecuencia permite al programador escribir las clases de objetos en un grado de abstracción más alto, por ende, haciendo más flexible futuras inclusiones de nuevos elementos en el dominio del problema. Veremos cómo lograr lo anterior a través de explicaciones sólidas y precisas acerca de este importantísimo concepto. Además, apreciáremos para empezar, los diferentes tipos de polimorfismo que existen, y su aplicación para entender más a fondo la la naturaleza de este pilar de la programación orientada a objetos.

1. Polimorfismo

1.1 Concepto de Polimorfismo

Aprovechando el concepto de polimorfismo de [4]:
Generally, the ability to appear in many forms. In object-oriented programming, polymorphism refers to a programming language's ability to process objects differently depending on their data type or class.
Podemos deducir que se trata de una característica que permite tratar de manera específica a los objetos (métodos, propiedades, etc.) dependiendo del tipo de objeto en cuestión. Esto nos lleva a pensar, además, en el concepto de herencia: donde una subclase hereda los miembros de una superclase. La subclase, en particular, tiene la posibilidad de redefinir la implementación de un miembro heredado.

Para ejemplificar, véamos los siguientes ejemplos:

Un teléfono inteligente puede adquirir diferentes formas, como serían:
  • Teléfono
  • Cámara
  • Reproductor de multimedia (audio y vídeo)
  • Radio
  • GPS
  • Agenda electrónica
Otro ejemplo correspondería con las condiciones de una persona de acuerdo al contexto de su ubicación:
  • En la universidad como Estudiante
  • En el trabajo como Empleado
  • En la casa como Hijo
  • En un sistema de transporte como Usuario del servicio

1.2 Tipos de Polimorfismo

Recurriendo a Wikipedia [2], encontramos los siguientes tipos de polimorfismos (los cuales me parecen importantes de tratar para tener una base más sólida sobre este pilar y hacer distinciones en futuros tratamientos de este concepto):

1.2.1 Polimorfismo ad-hoc

Se refiere a la capacidad de tener diferentes versiones (o firmas) de un método. Esto en programación se conoce como sobrecarga [10]. Las diferencias radican en el tipo y número de los argumentos definidos en cada una de las versiones sobrecargadas del método o función, el factor común está en el uso del mismo nombre para referirse a la función.

Veamos un ejemplo con la clase Calculadora que contiene tres versiones sobrecargadas del método Suma:

► Prueba de ejecución.

1.2.1 Polimorfismo paramétrico

Cuando de plantillas -concepto de C++- o genéricos -de Java- se habla de polimorfismo paramétrico. La implementación de un método o función es independiente de los tipos de datos pasados como argumentos.

En las estructuras de datos podemos apreciar una exposición sencilla y práctica de entender. En particular con la estructura de datos Lista simple [11].

Archivo C# List.cs [enlace alternativo]:
► Prueba de ejecución.

1.2.3 Subtipado

El subtipado es un mecanismo que permite crear restricciones sobre el tipo de datos que pueden ser utilizado en un caso particular de polimorfismo [2]. Básicamente este mecanismo es logrado a través de la herencia.

Veamos un ejemplo:
Herencia Figuras
Figura 1. Herencia de Objetos Figura.

En este caso el polimorfismo se puede aplicar utilizando los tres métodos definidos en Figura:
  • Dibujar()
  • EstablecerColor()
  • ObtenerColor()
Al crear instancias de los tipos de objetos Circulo, Triangulo, y Rectangulo y que cada uno de estas instancias invoque los métodos mencionados anteriormente, sólo se ejecuta la versión de la implementación no heredada sino la sobrescrita en cada uno de los tipos.

2. Polimorfismo en C#

El polimorfismo en C# funciona de forma análoga a otros lenguajes de programación orientados a objetos (como Java y C++).

Vamos a afianzar este concepto sobre C# utilizando la jerarquía de clases de la Figura 1.

Archivo C# Figura.cs [enlace alternativo]:
Archivo C# Circulo.cs [enlace alternativo]:
Archivo C# Triangulo.cs [enlace alternativo]:
Archivo C# Rectangulo.cs [enlace alternativo]:
Archivo C# ProgramaFigura.cs [enlace alternativo]:

Obsérvese como en las líneas 9-11 se agregan a la lista de objetos de tipo Figura tres instancias anónimas de las derivadas (i.e.Circulo, Triangulo, y Rectangulo). Pero es aún más relevante lo que ocurre en el ciclo for mejorado -foreach-: se recorre la lista de objetos en la lista figuras y en cada uno se invoca el método figuras de manera polimórfica (no es necesario ningún cambio/conversión de tipos: el compilador sabe cuál método invocar en tiempo de ejecución).

3. Aspectos Intrínsecos de Polimorfismo en C#

3.1 Tipos de polimorfismo en C#

En C# encontramos dos tipos de polimorfismos intrínsecos al lenguaje como tal. En la Figura 2 [12] se muestra la categorización:
Tipos de polimorfismo en C#
Figura 2. Tipos de polimorfismo en C# [12].

3.1.1 Polimorfismo estático o de tiempo de compilación

De acuerdo con [12], el polimorfismo estático corresponde con las decisiones de invocación durante el proceso de compilación. Tiene las siguientes características:
  • Decide la versión del método a ejecutar.
  • Corresponde con el tipo de polimorfismo ad-hoc (ver sección 1.2.1). Respecto a esto el compilador descubre y sabe cuál método debe ser llamado de acuerdo al tipo y longitud de parámetros.
[Nota: Ver ejemplo de la sección 1.2.1]

3.1.2 Polimorfismo dinámico o de tiempo de ejecución

Este tipo de polimorfismo se logra mediante la sobrescritura de métodos derivados de la clase base. Aquí la CLR se encarga de resolver el método a invocar sobre el tipo derivado. Es decir, si tuviéramos algo como esto:

foreach (Figura figura in figuras)
{
figura.Dibujar();
}

la máquina virtual en tiempo de ejecución (evidentemente) el método sobrescrito a ejecutar dependiendo del tipo de la referencia.

Ahora vayamos con un ejemplo más particular.


La clave para alcanzar ese efecto se logra a través de la especificación de virtual [13] en el método Imprimir sobre la clase base; y la sobrescritura del mismo método especificado con el modificador override [14].

4. Polimorfismo con Interfaces

A través de interfaces también podemos implementar el polimorfismo. Uno de los ejemplos básicos y comunes donde se usan interfaces es la estructura de datos. Miremos la Figura 3.
IEnumerable
Figura 3. Interfaz IEnumerable en estructura de datos.

La interfaz IEnunmerable [15] permite crear una relación entre objetos que son parte de la jerarquía de herencia de estructuras de datos en C#. Cada tipo de objeto en esta jerarquía implementa el método GetEnumerator, lo cual permite iterar o recorrer el conjunto de elementos disponibles en una instancia de la estructura de datos en cuestión (e.g., una lista, o una pila).

5. Conclusiones

Hemos aprendido varios aspectos acerca de polimorfismo en C#. Pudimos entender el concepto, y su utilidad para permitir al programador crear los elementos de resolución del dominio del problema con mayor grado de abstracción. Esta característica va a facilitar, en concreto, la fácil adición de nuevos elementos y la extensibilidad de la aplicación en futuras iteraciones del desarrollo. Reconocimos los diferentes tipos de polimorfismo disponibles, pero también los particulares en lenguaje C# (estático y dinámico). Vimos ejemplos que demuestran este poderoso pilar de la programación orientada a objetos.

6. Glosario

  • Ad-hoc
  • Dinámico
  • Estático
  • Estructura de Datos
  • Genérico
  • Lista
  • Plantilla
  • Polimorfismo
  • Sobrecarga
  • Sobrescritura
  • Virtual

7. 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]: Polymorphism (computer science) - Wikipedia, the free encyclopedia - http://en.wikipedia.org/wiki/Polymorphism_(computer_science)
[3]: Polymorphism (The Java™ Tutorials > Learning the Java Language > Interfaces and Inheritance) - http://docs.oracle.com/javase/tutorial/java/IandI/polymorphism.html
[4]: What is polymorphism? - A Word Definition From the Webopedia Computer Dictionary - http://www.webopedia.com/TERM/P/polymorphism.html
[5]: polymorphism - Wiktionary - http://en.wiktionary.org/wiki/polymorphism
[6]: 01 07 What is polymorphism - YouTube - http://www.youtube.com/watch?v=akYhBjdM_MY
[7]: JavaRanch Campfire - How my Dog learned Polymorphism - http://www.javaranch.com/campfire/StoryPoly.jsp
[8]: Polymorphism (C# Programming Guide) - http://msdn.microsoft.com/en-us/library/ms173152.aspx
[9]: C# Polymorphism - http://www.tutorialspoint.com/csharp/csharp_polymorphism.htm
[10]: Function overloading - Wikipedia, the free encyclopedia - http://en.wikipedia.org/wiki/Function_overloading
[11]: List (abstract data type) - Wikipedia, the free encyclopedia - http://en.wikipedia.org/wiki/List_(abstract_data_type)
[12]: Polymorphism in .NET - CodeProject - http://www.codeproject.com/Articles/602141/Polymorphism-in-NET
[13]: virtual (C# Reference) - http://msdn.microsoft.com/en-us/library/9fkccyh4(v=vs.110).aspx
[14]: override (C# Reference) - http://msdn.microsoft.com/en-us/library/ebca9ah3.aspx
[15]: IEnumerable Interface (System.Collections) - http://msdn.microsoft.com/en-us/library/system.collections.ienumerable(v=vs.110).aspx


O

2 comentarios:

  1. Interesante aunque no veo la especificación de interfaces como forma de implementación del polimorfismo.

    ResponderEliminar

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