Polimorfismo (programación orientada a objetos)
De Wikipedia, la enciclopedia libre
| La exactitud de la información de este artículo está discutida. En la página de discusión puedes consultar el debate al respecto. |
En programación orientada a objetos se denomina polimorfismo a la capacidad que tienen los objetos de una clase de responder al mismo mensaje o evento en función de los parámetros utilizados durante su invocación. Un objeto polimórfico es una entidad que puede contener valores de diferentes tipos durante la ejecución del programa.
En algunos lenguajes, el término polimorfismo es también conocido como 'Sobrecarga de parámetros' ya que las características de los objetos permiten aceptar distintos parámetros para un mismo método (diferentes implementaciones) generalmente con comportamientos distintos e independientes para cada una de ellas.
Ejemplo:
' este método devuelve la suma de 2 parámetros Function suma(int numero1,int numero2) ' este método devuelve la suma de los 3 parámetros Function suma(int numero1,int numero2, int numero3) ' este método devuelve la concatenación de cadena1 y cadena2 Function suma(String cadena1, String cadena2)
En el ejemplo mostrado, los 3 métodos pertenecen a la misma clase (que será un objeto una vez instanciado y en memoria). Nótese que el nombre del método es siempre el mismo; estos se diferencian entre sí por:
- La cantidad de parámetros.
- El orden en que se ubican los parámetros al invocar al método.
- El tipo de dato de los parámetros.
Nota: en los lenguajes que no son 'fuertemente tipados' el polimorfismo no tiene en cuenta el tipo de dato de cada parámetro.
También se puede aplicar a la propiedad que poseen algunas operaciones de tener un comportamiento diferente dependiendo del objeto (o tipo de dato) sobre el que se aplican. El polimorfismo sólo es aplicable si cualquiera de los posibles tipos de objetos que se invoquen tienen definida la operación empleada, y los tipos de datos de entrada requeridos y los valores devueltos, más allá de cómo se empleen o calculen, son compatibles entre sí.
El concepto de polimorfismo se puede aplicar tanto a funciones como a tipos de datos. Así nacen los conceptos de funciones polimórficas y tipos polimórficos. Las primeras son aquellas funciones que pueden evaluarse o ser aplicadas a diferentes tipos de datos de forma indistinta; los tipos polimórficos, por su parte, son aquellos tipos de datos que contienen al menos un elemento cuyo tipo no está especificado.
[editar] Clasificación
Se puede clasificar el polimorfismo en dos grandes clases:
- Polimorfismo dinámico (o polimorfismo paramétrico) es aquél en el que el código no incluye ningún tipo de especificación sobre el tipo de datos sobre el que se trabaja. Así, puede ser utilizado a todo tipo de datos compatible.
- Polimorfismo estático (o polimorfismo ad hoc) es aquél en el que los tipos a los que se aplica el polimorfismo deben ser explicitados y declarados uno por uno antes de poder ser utilizados.
El polimorfismo dinámico unido a la herencia es lo que en ocasiones se conoce como programación genérica.
También se clasifica en herencia por redefinición de métodos abstractos y por método sobrecargado. El segundo hace referencia al mismo método con diferentes parámetros.
Otra clasificación agrupa los polimorfismo en dos tipos: Ad-Hoc que incluye a su vez sobrecarga de operadores y coerción, Universal (inclusión o controlado por la herencia, paramétrico o genericidad).
[editar] Polimorfismo desde una interfaz
Aunque el polimorfismo es el mismo se aplique donde se aplique, el modo es que se aplica desde una interfaz puede resultar un poco más oscuro y difícil de entender. Se expone un sencillo ejemplo comentado para entender como funciona aplicado desde una interfaz, primero se escribe el código y luego se comenta el funcionamiento. Nota: para no enturbiar el código en exceso, todo lo que no se declara privado se sobreentiende público.
' Declaramos una interfaz llamada IOperar y declaramos una función llamada Operar ' que implementarán las clases deseadas: Interface IOperar Function Operar(valor1 as integer, valor2 as integer) as long End Interface
' Declaramos una clase que trabaja más alejada del usuario y que contendría funciones comunes ' para las siguiente clase, si no fueran idénticas irían en la interfaz, ' pero al caso de mostrar el polimorfismo se suponen idénticas: Class Operacion Function Calcular(clasellamante as Object) as Long ' aquí iría el código común a todas las operaciones.... que llaman a esa función ' por ejemplo recoger los 2 valores de la operación, chequear que están en el rango deseado, etc... ' se supone que la función inputValor recoge un valor de algún sitio valor1 as integer = inputValor() valor2 as integer = inputValor() op as New IOperar = clasellamante Return op.Operar(valor1,valor2) 'AQUÍ es donde se utiliza el polimorfismo. End Function End Class
' Declaramos 2 clases: Sumar y Resta que implementan la interfaz y que llaman a la clase Operacion: Class Sumar Implements IOperar Private Function Operar(valor1 as Integer, valor2 as Integer) as Long Implements IOperar.Operar Return valor1 + valor2 End Function Function Calcular() as Long op as New operacion Return op.Calcular(Me) ' se está llamando a la función 'Calcular' de la clase 'Operación' End Function End Class
' segunda clase.... Class Restar Implements IOperar Private Function Operar(valor1 as Integer, valor2 as Integer) as Long Implements IOperar.Operar Return valor1 - valor2 End Function Function Calcular() as Long op as New operacion Return op.Calcular(Me) ' se está llamando a la función 'Calcular' de la clase 'Operación' End Function End Class
- Analicemos ahora el código para entender el polimorfismo expuesto en la interfaz: La interfaz expone un método que puede ser implementado por las diferentes clases, normalmente relacionadas entre si. Las clases Sumar y Restar implementan la interfaz pero el método de la interfaz lo declaramos privado para evitar ser accedido libremente y además tienen un método llamado Calcular que llama a la clase Operacion donde tenemos otro método con el mismo nombre. Es esta clase última la que realiza el polimorfismo y debe fijarse como es a través de una instancia de la interfaz que llama al método operar. La interfaz sabe a qué método de qué clase llamar desde el momento que asignamos un valor a la variable OP en el método Calcular de la clase Operacion, que a se vez recibió la referencia del método Calcular desde la clase que la llama, sea está cual sea se identifica a sí misma, mediante la referencia Me ó This según el lenguaje empleado. Debe notarse que la instancia de la interfaz accede a sus métodos aunque en sus clases se hayan declarado privadas.
[editar] Ventajas del polimorfismo frente a la sobrecarga
El polimorfismo como se muestra en el ejemplo anterior, suele ser bastante ventajoso aplicado desde las interfaces, ya que permite crear nuevos tipos sin necesidad de tocar las clases ya existentes (imaginemos que deseamos añadir una clase Multiplicar), basta con recompilar todo el código que incluye los nuevos tipos añadidos. Si se hubiera recurrido a la sobrecarga durante el diseño exigiría retocar la clase anteriormente creada al añadir la nueva operación Multiplicar, lo que además podría suponer revisar todo el código donde se instancia a la clase.

