Polimorfismo

El Polimorfismo describe múltiples y posibles estados de una única propiedad. Es una de las propiedades fundamentales de la programación orientada a objetos y es también una técnica utilizada por virus informáticos y gusanos para modificar partes de su código dificultando su detección.

¿Qué es?

  En programación orientada a objetos el polimorfismo se refiere a la posibilidad de definir clases diferentes que tienen métodos o atributos denominados de forma idéntica, pero que se comportan de manera distinta. 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.

  El polimorfismo tiene que ver con la relación que se establece entre la llamada a un método y el código que efectivamente se asocia con dicha llamada. A esta relación se le llama vinculación (binding). La vinculación puede ser temprana (en tiempo de compilación) o tardía (en tiempo de ejecución). Con funciones normales o sobrecargadas se utiliza vinculación temprana (es posible y es lo más eficiente). Con funciones redefinidas se utiliza siempre vinculación tardía, excepto si el método es final. El polimorfismo es la opción por defecto en Java.

 

  La vinculación tardía hace posible que, con un método declarado en una clase base (o en una interface) y redefinido en las clases derivadas (o en clases que implementan esa interface), sea el tipo de objeto y no el tipo de la referencia lo que determine qué definición del método se va a utilizar. El tipo del objeto al que apunta una referencia sólo puede conocerse en tiempo de ejecución, y por eso el polimorfismo necesita evaluación tardía. 

 

Polimorfismo de Métodos

  Polimorfismo (en POO) es la capacidad que tienen ciertos lenguajes para hacer que, al enviar el mismo mensaje (o, en otras palabras, invocar al mismo método) desde distintos objetos, cada uno de esos objetos pueda responder a ese mensaje (o a esa invocación) de forma distinta. Ésto es conocido como polimorfismo de métodos.Un mismo método puede dar distintas respuestas cuando se le llama a través de distintos objetos. Algunos autores definen otro tipo de polimorfismo, el

polimorfismo de objetos, nos permitía definir estructuras genéricas (que está basado en la idea de que un objeto de una subclase, pertenece, aparte de al tipo correspondiente a dicha clase, al tipo de todas sus clases base).

 

  Hay dos ingredientes básicos necesarios para que tenga sentido hablar de polimorfismo de métodos.

  1.  Que tengamos definidas ciertas relaciones de herencia entre clases
  2.  Que exista redefinición de algún método

 

Tipos

 

  • Polimorfismo de sobrecarga

 

  El polimorfismo de sobrecarga ocurre cuando las funciones del mismo nombre existen, con funcionalidad similar, en clases que son completamente independientes una de otra (éstas no tienen que ser clases secundarias de la clase objeto). Por ejemplo, la clase complex, la clase image y la clase link pueden todas tener la función “display”. Esto significa que no necesitamos preocuparnos sobre el tipo de objeto con el que estamos trabajando si todo lo que deseamos es verlo en la pantalla.

  Por lo tanto, el polimorfismo de sobrecarga nos permite definir operadores cuyos comportamientos varían de acuerdo a los parámetros que se les aplican. Así es posible, por ejemplo, agregar el operador + y hacer que se comporte de manera distinta cuando está haciendo referencia a una operación entre dos números enteros (suma) o bien cuando se encuentra entre dos cadenas de caracteres (concatenación).

 

  • Polimorfismo paramétrico(también llamado polimorfismo de plantillas)

 

  El polimorfismo paramétrico es la capacidad para definir varias funciones utilizando el mismo nombre, pero usando parámetros diferentes (nombre y/o tipo). El polimorfismo paramétrico selecciona automáticamente el método correcto a aplicar en función del tipo de datos pasados en el parámetro.

  Por lo tanto, podemos por ejemplo, definir varios métodos homónimos de addition() efectuando una suma de valores.

*El método int addition (int,int) devolvería la suma de dos números enteros.

*El método float addition (float, float) devolvería la suma de dos flotantes.

*El método char addition (char, char) daría por resultado la suma de dos caracteres definidos por el autor.

  Una signature es el nombre y tipo (estático) que se da a los argumentos de una función. Por esto, una firma de método determina qué elemento se va a llamar.

 

  • Polimorfismo de inclusión (también llamado redefinición o subtipado)

 

  La habilidad para redefinir un método en clases que se hereda de una clase base se llama especialización. Por lo tanto, se puede llamar un método de objeto sin tener que conocer su tipo intrínseco: esto es polimorfismo de subtipado. Permite no tomar en cuenta detalles de las clases especializadas de una familia de objetos, enmascarándolos con una interfaz común (siendo esta la clase básica).

Polimorfismo vs Sobrecarga

  • El polimorfismo, 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.
  • La sobrecarga se da siempre dentro de una sola clase, mientras que el polimorfismo se da entre clases distintas.
  • Un método está sobrecargado si dentro de una clase existen dos o más declaraciones de dicho método con el mismo nombre pero con parámetros distintos, por lo que no hay que confundirlo con polimorfismo.
  • En definitiva: La sobrecarga se resuelve en tiempo de compilación utilizando los nombres de los métodos y los tipos de sus parámetros; el polimorfismo se resuelve en tiempo de ejecución del programa, esto es, mientras se ejecuta, en función de qué clase pertenece un objeto.

Ejemplo:

  Cuando invocamos al método “getSalario(): double” sobre el objeto “empl2”, en un compilador de “enlazado dinámico”, en tiempo de ejecución, “empl2” comprueba su tipo (a qué clase pertenece), y el compilador se dirige a dicha clase (“EmpleadoDistribucion”) a buscar una definición del método. Si encuentra dicha definición, como es el caso, la “enlaza” con “empl2” y hace uso de ella.

  El compilador así ha evitado hacer uso del método “getSalario(): double” tal y como éste está definido en la clase “Asalariado”. 

  Si invocamos a un método que no está redefinido en la clase  “EmpleadoDistribucion” sobre el objeto “empl2” el proceso será el siguiente: El compilador busca una definición del método en la clase “EmpleadoDistribucion”. Como éste no existe, sube un nivel, a la clase “Asalariado”, y repite la búsqueda. En este caso la respuesta es afirmativa, y utiliza esa definición del método.

Conclusión

  El polimorfismo permite a los programadores separar las cosas que cambian de las que no cambian, y de esta manera hacer más fácil la ampliación, el mantenimiento y la reutilización de los programas.

  En Java siempre hay comportamiento polimorfo de métodos, y que tal comportamiento no requiere ninguna modificación por parte del programador.


Muchas gracias por haber llegado hasta acá ¡Esperamos que te haya servido este material! Si fue así no dudes en compartir el blog con tus compañer@s, darle like al post en redes o comentar tu devolución del mismo.