¿Quieres saber que es el Polimorfismo? En el siguiente artículo, te daremos una detallada información sobre lo que es el denominado Polimorfismo en programación orientada a objetos.

poliformismo-en-programacion-orientada-objetos-1

Polimorfismo en programación orientada a objetos

Aunque pueda parecer una palabra con una descripción algo compleja, realmente este tipo de tema relacionado a la informática  se relaciona a aspectos totalmente básicos de la misma. Cuando se aprende Programación Orientada a Objetos, podemos toparnos con esta descripción, cuyo significado es sencillamente la descripción de múltiples y posibles estados de una única propiedad.

Para la informática, es una de las propiedades fundamentales para la programación orientada a objetos y es también una técnica utilizada para virus informáticos o gusanos para modificar partes de su código dificultando su detección. Esto puede facilitar mucho las cosas a la hora de programar algo cuando no queremos ser tan específicos y necesitamos algo más funcional que se adapte a una manera más amplia de trabajar, que nos reduzca el trabajo y nos ayude a poder manejar algo más dinámico y flexible.

Antes de saltar directo al grano estaremos explicando algunos conceptos y desglosando definiciones que nos servirán como abreboca, no solo para entenderlo mejor, sino para entender su funcionamiento, su importancia, y lo útil que nos puede ser en el campo de la informática, ayudándonos a relajar nuestro trabajo. Posiblemente no encontraremos nada nuevo antes de saltar directamente al polimorfismo en programación orientada a objetos, pero es importante tener todo lo siguiente en cuenta para poder comprender apropiadamente.

El concepto de polimorfismo en programación orientada a objetos tiene su origen en el Simula 67, el cual es un lenguaje de programación, hecho para realizar simulaciones. Esto fue creado por Ole Joha Dahl y Kristen Nygaard quienes pertenecían al centro de cómputo noruego en Oslo.

Este centro se dedicaba a la simulación de naves, hubo mucha confusión por la explosión por la diferencias entre unas y otras, cuando estas naves fueron agrupadas por su respectiva clasificación para generar más control al momento de hacer los estudios fue entonces cuando esta idea salió a flote.

Este estilo de programación en los años 80’s predominaba en casi todos los ámbitos de la informática por su gran atribución con C++ que es otro lenguaje de programación C. Gracias a las interfaces gráficas de usuario la dominación de este método funciono muy bien.

El polimorfismo en programación orientado a objetos posee diversas características, las cuales fueron aplicadas en diferentes lenguajes que se usaban en esa época como lo son: Ada, BASIC, LISP, Pascal, entre muchos otros, aunque estos desarrollaron diversos problemas de compatibilidad.

Para una explicación más detallada sobre lo que es el Polimorfismo en programación orientada a objetos, te invitamos a ver el siguiente vídeo:

El Polimorfismo y la Herencia

El prefijo poli tiene su origen en el griego por lo que su descripción exacta quiere decir  abundancia, muchos o variedad, y morfismo es un sufijo griego que entra en la formación de palabras con el significado de forma, composición, o estructura de un cuerpo. Tomando esto en cuenta, podemos adentrarnos en lo que queremos explicar en este fragmento, nuestra palabra protagonista es básicamente por definición una variedad formada por la estructura de un cuerpo; en varios campos de las matemáticas, se llaman morfismos a las aplicaciones entre estructuras matemáticas que preservan la estructura interna.

Para poder dejar esto completamente claro, podemos comparar polimorfismo y herencia. Es decir que esto nos permite lleva a cabo los polimorfismo en jerarquías de clasificación. es importante además mencionar que estos se dan a través de herencia, siempre y cuando, la herencia, que podríamos entender como derivados de un objeto, siempre pertenezca a la misma clase; para poner un ejemplo de lo explicado, podemos decir que de la palabra vehículo, se desprenden varias clases, como lo sería un auto, una moto, y un autobús, viéndolo de esta manera, el polimorfismo y la herencia son dos conceptos innegablemente ligados.

La importancia del Sistema de Tipos en el Polimorfismo

Nombrando a esta clasificación como sistema de tipos, porque los derivados de esa palabra siguen formando parte de ellas, pero ¿Por qué es este importante en el polimorfismo en programación orientada a objetos?.

Muchas de las personas que entraron en este artículo, podrían estar familiarizados con lo que es programar en lenguajes débilmente tipados, como lo sería en el caso de Javascript y PHP, de todos modos es importante que entendamos bien cómo es.

En este tipo de lenguajes, al definir una variable, siempre tenemos que señalar el tipo que queremos que contenga esa variable, por ejemplo: int miNumero.

De este modo tenemos la posibilidad de indicar que la variable establecida como «miNumero» siempre contendrá un número entero; de ser otro el caso, el compilador nos lanzaría un mensaje de error obstaculizándonos la posibilidad de compilar el programa que hayamos realizado.

De hecho esto también puede pasarnos con los objetos, si en Java definimos la clase «largometraje», conociendo está palabra como una película cinematográfica de duración superior a una hora, cuando creamos objetos de la clase «largometraje» debemos señalar las variables en las que se indique el tipo de objeto que se pretende que realice. Podemos expresarlo de esta manera:

Largometraje miLargo= new Largometraje

Nuestra variable vendría siendo «miLargo» y exponiendo esto, tendremos una referencia a un objeto de la clase o de los tipos de «Largometraje», y mientras que dure siempre deberá tener cualquier objeto de la misma clase o tipo, dicho esto es importante conocer entonces que no se puede guardar un entero en la variable, o algún otro objeto de otro tipo o clase, que no sea herencia y que no tenga ninguna relación.

Si volvemos a mencionar el ejemplo de los vehículos y sus tipos, es importante aclarar que si decidimos definir una variable que apunte hacia el objeto de clase «moto», mientras está variable dure, siempre deberá apuntar a un objeto relacionado o de herencia a la clase «moto», no a la clase «coche», ni «bus»; sin embargo, en los lenguajes débilmente tripados como los que mencionamos anteriormente, no existe esta inflexibilidad, aunque sea una característica habitual de los lenguajes como Java que son fuertemente tripados. A continuación ofreceremos un ejemplo más amplio:

  • Coche miCoche= new Coche (Mazda 2″): Mazda 2 vendría siendo nuestra herencia del objeto perteneciendo a esa clase o tipo, y es al que la variable apunta, y si así lo quisiéramos mañana podría apuntar hacia otro objeto de miCoche.

MiCoche= new Coche (Ford Focus 2.0″)

Lo que nunca podremos hacer es almacenar en nuestra variable establecida como de clase Coche, otra cosa que no tenga ninguna relación con el tipo Coche, porque entonces tendríamos un error en tiempo de compilación, en caso de que pase, debe haber guardado New Coche Ford Focus 2.0 hubiéramos escogido New Moto Yamaha YBR.

Se debe aclarar que en este punto no estamos hablando de polimorfismo como tal aún, sino que estamos tanteando la programación en general con el sistema de tipos; el asunto es que debemos abrir nuestras mentes a las complicaciones que puede darnos la restricción de lenguajes fuertemente tripados para luego comprender porqué el polimorfismo es importante y una pieza clave en el polimorfismo en programación orientada a objetos.

En un idioma informático totalmente tipado cuando se manifiesta una función, siempre debemos mantener como punto de importancia que al informar el tipo de  normas que va a recibir. A la función que hayamos establecido, no le podremos pasar como normas otra cosa que no sean variables o literales con valores de número entero, si se nos ocurre pasar otros datos con otros tipos el compilador se va a alterar, no nos dejará compilar el programa porque en tal caso no podría encontrar los tipos esperados en los parámetros de la función.

moto-auto-1

Polimorfismo en objetos

Finalmente hemos llegado a la parte que realmente puntualiza este tema de interés, es por ello que bajo este sistema se efectuarán elementos propios que manifiesten las clases y objetivos del mismo, tal cual funcionan los lenguajes fuertemente tipados, una variable siempre deberá apuntar a un objeto de la clase que indicamos al momento en que lo establecimos.

Eso es algo indispensable de recordar, ahora, una función cuyo parámetro se haya declarado de una clase, solo nos aceptará recibir objetos de esa clase; un array que se haya declarado que es de elementos de un tipo determinado solo nos permitirá rellenar sus casillas con objetos de ese tipo que establecimos; presentaremos otro ejemplo:

Vehículo [ ] misVehiculos= new Vehículo [3]

Este ejemplo estamos dando, es una variable que es un array y en la misma declaramos  que el contenido de las casillas serán objetos de la clase Vehículo, en lenguaje fuertemente tripado solo podrá contener objetos de la clase vehículo, como ya habíamos explicado, pero ahora nos encontramos con el polimorfismo, con el cual podemos darle un poco más de flexibilidad al sistema de tipos, dándonos la oportunidad de que una variable también nos acepte objetos de la clase «hijas» o derivadas.

Al hacer al sistema de tipos más flexible no estamos hablando de en su totalidad, sino con lo que tendría que ver con las clasificaciones de herencia que tengamos en nuestros sistemas de clases o tipos. Si logramos definir un array usando casillas de una clase establecida, el compilador nos aceptaría insertar en esas casillas palabras «hijas» de ese objeto que ya habíamos establecido, si establecemos que una función recibe como parámetros objetos de alguna clase, el compilador nos permitirá que le enviemos la invocación de objetos de una clase derivada de aquella que ya habíamos declarado.

Llevándolo a algo más concreto, nuestro array de vehículo no solo nos permitirá insertar vehículos genéricos a su variable, sino también todos los objetos de las clases hijas o derivadas de esta clase, entonces tendríamos objetos de la clase bus, coche y moto o cualquier hija que hayamos definido, y todo esto gracias al polimorfismo.

Aplicando el Polimorfismo

A pesar de la explicación que le habíamos dado a largometraje, queremos aclarar que además de ser una película, podemos también tener documentales, y entre otros; quizá ambos tienen diferentes características, distintos horarios de audiencia, distintos precios y por ello pudimos haber decidido que nuestra clase Largometraje tenga clases hijas o herencias como «película» o «documental».

Si creamos una clase establecida como Cine y un método al que llamaremos «reproducir», nos servirá como parámetro para aquello que queremos reproducir en una sala de cine, donde podrán llegamos objetos tanto de la clase cine como de la clase documental, si comprendemos bien el sistema de tipos (sin aun entrar en polimorfismo) nuestros métodos van a establecer los tipos de los parámetros que recibimos. Se vería algo como esto:

  • Reproducir (Película películaParaReproducir)

Pero en cambio si queremos reproducir un documental tendríamos que cambiar nuestra fórmula.

  • Reproducir (Documental documentalParaReproducir)

¿Y es realmente necesario crear dos fórmulas distintas? Ambos métodos para reproducir las dos cosas serían exactamente los mismos, ¿Por qué molestarse? Solo tendríamos que poner el largometraje en el reproductor, darle a reproducir (o play) y crear un registro con la cantidad de entradas que lograron ser vendidas. Aunque no nos suponga una molestia hacer ambos métodos, debemos estar conscientes de que se nos puede presentar la situación en la que tengamos que crear otra fórmula, podríamos poner el ejemplo de que tengamos una película, pero esta vez en formato 3D.

Ya llegados a este punto, podemos recurrir al polimorfismo, con su ayuda podremos crear un método de reproducir que nos reconocerá todo tipo de elementos, documentales, películas o cualquier otra cosa de la misma clase (que tenga relación), que necesitemos crear en el futuro. Lo que nos estarían permitiendo los lenguajes, es establecer el método reproducir indicando que el parámetro de la clase que vamos a recibir es un objeto de tipo largometraje, pero el lenguaje y el compilador nos estarían aceptando cualquier objeto derivado de película o documental, quedaríamos con algo como esto: reproducir (Largometraje elementoParaReproducir).

Ya sea que queramos crear películas o documentales para reproducirlos, todo esto será posible con un solo método, el de reproducir, gracias a que por el polimorfismo en programación orientada a objetos flexibilizamos el sistema, no hará falta. Por ejemplo, si quieres reproducir una película y no un documental, no nos veremos en la necesidad de seleccionar la clase Cine, sino que solo basta con que lo que queramos reproducir forme parte de la herencia del objeto largometraje.

Si nos regresamos al ejemplo del vehículo, aun teniendo en mente la utilidad del polimorfismo y las posibilidades que nos brinda para reducir todo el mantenimiento de los programas informáticos que tendríamos que hacer de no tener la ayuda de este concepto.

Digamos que tenemos la clase Parking (en español seria la clase para aprender a estacionar) dentro de la que tenemos la función de estacionar. En un estacionamiento tenemos la posibilidad de estacionar autobuses y motos, además de solamente coches, y sin polimorfismo tendríamos que crear un método que nos permita estacionar objetos de tipo «coche» y otro que nos permita estacionar objetos de tipo «autobús» y otro que nos permita estacionar objetos de tipo «moto», aunque el procedimiento para realizar estas acciones a pesar de la notable diferencia entre las apariencias de estos tres vehículos es básicamente la misma, solo que uno ocupa más espacio que el otro.

Lo más preciso sería tener un solo método que nos simplifique las cosas y nos permita recibir todo tipo de vehículos, no solo coches y marca de coches, sino todos los derivados aceptados y preciosos del objeto vehículo. Primero tendríamos la reutilización del código, porque como ya habíamos dicho, estacionar esos tipos de vehículos es parecido con la única diferencia del espacio que ocupa cada uno, pero además de esto, si mañana saliese a la venta en el mercado algún otro tipo de vehículo, tendríamos la posibilidad de que nuestro software sea capaz de aceptarlo sin ninguna necesidad de modificar nuestra clase ya establecida Parking.

Tenemos a la disposición de un solo método la aceptación de todas las herencias precisas que pueda tener vehículo, flexibilizando el trabajo y ahorrándonos el tiempo que nos habríamos gastado creando uno para cada tipo de vehículo. El polimorfismo en programación orientada a objetos nos abre las puertas a una gama de objetos que pueden ser aceptadas por un solo método.

Intentamos explicar de la manera más comprensible el polimorfismo y hacer una revisión amplia de todo lo que hay detrás del mismo, no habría sido adecuado saltar de una vez al concepto como tal sin proveer sus antecedentes para ayudarnos a entenderlo y a entender su resaltante importancia y el uso que podemos darle.

Tener la posibilidad de poder englobar varios métodos en uno solo, mientras las derivaciones concuerden como herencia del objeto, es bastante útil porque nos ahorra la necesidad de tener que crear varios obligándonos a ser muy específicos sin darnos la posibilidad de hacer un trabajo más flexible en el que podamos crear una manera más dinámica de manejar lo que hayamos programado, tan simple como saber la derivación correcta de una sola palabra, es decir, todo lo que engloba, nos ayuda a hacer un trabajo más eficaz.

Esperamos disfrutarás este artículo y aprendieras que es el polimorfismo en programación orientada a objetos. Si deseas leer otro de nuestros artículos sobre programación, te recomendamos visitar el siguiente que nos brinda una forma de programación muy conocida en el mundo de la informática: Programación C++.