Polimorfismo

El polimorfismo es quizá al característica más importante de la programación orientada a objetos y también quizá la más difícil de entender y creo que en parte se debe al nombre; no ayuda mucho y si impresiona al principio.

Pero si en vez de pensar en la palabra pensamos en como los objetos se comportan de diferente forma dependiendo de su naturaleza puede ser más claro.

Por ejemplo, en el post anterior Clases y Objetos hablaba como los objetos de nuestros sistema se pueden clasificar de acuerdo a sus atributos y comportamiento. Los objetos de la misma clase se comportan igual y los objetos de diferentes clases se comportan diferente. ¿Parece demasiado obvio verdad? Pues es que lo es.

Por ejemplo, el mecanismo de persistencia ( entiéndase, cuando voy a "salvar", o "guardar" algo ) puede utilizar una base de datos o el sistema de archivos entonces se tendrían dos clases diferentes donde cada una hiciera algo distinto.

Si tuvieramos esta clase llamada Persona:

 

Podríamos escribir una clase que persistiera personas a una base de datos así:

 

El código para salvar a la base de datos no importa mucho en este ejemplo, basta con ver que se utiliza una sentencia SQL y por ahí una biblioteca mágica que haga todo el trabajo.

Podríamos también tener otra clase que en vez de usar una base de datos escribiera a un archivo:

 

De nuevo la implementación aquí no es la importante, sino que tenga un método que recibe una instancia de persona y hace algo.

De esto se trata el polimorfismo! de que diferentes clases responden de diferente forma al mismo mensaje ( mensaje es cuando se invoca o se ejecuta un método ), en este caso el mensaje o el método fue   y las dos clases lo hicieron de forma diferente. Eso es todo.

Ahora. En Java, el tipo de dato ( la clase ) del objeto se debe de declarar antes de que el programa se ejecute ( por eso se le llama de tipeo estático, por que los tipos de datos se definen "en frio" )

 

Otros lenguajes permiten definir el tipo de dato en tiempo de ejecución ( tipeo dinámico )

Como a los objetos solo se les pueden enviar mensajes que estén definidos en su propia clase, habría problema para intentar hacer esto:

 

El problema es que la variable   fue declarada como de tipo   y por lo tanto ya no se le puede asignar el tipo  

En Java existen dos formas de solucionar este problema, la primera es definir una clase padre para ambas clases y definir el tipo de dato como el de esa clase:

 

Y luego

 
y
 

Y definir el tipo de datos como el del padre:

 

Y dadaaaa!!! ya tenemos polimorfismo.

La otra opción es implementando una interfaz pero ya veremos eso después.

Conclusión

Si parece demasiado fácil hacer polimorfirsmo en Java y se quedan con la idea de "Que!! eso es todo?!" pues les diré que sí, eso es todo.

Lo interesante aquí viene en la forma en la que se utiliza el polimorfismo y porque es tan importante en la POO.

Por ejemplo en los plugins se escribe código y se llaman métodos sobre clases que ni siquiera existen aún, porque será el autor del plugin el que provea esa nueva funcionalidad.

De la misma forma, la gran mayoría de los famosos patrones de diseño se basan precisamente en esto, en el polimorfismo para que sean las implementaciones las que digan que es lo que se va a hacer.

Y en el ejemplo mismo que es tan burdo, se puede agregar fácilmente quizá un año después de haber escrito este pedazo de código, un nuevo "Guardador" que utilice la red en vez de la base de datos o el sistema de archivos, bastaría definir el nuevo método:

 

Con lo que tendríamos un nuevo guardador. Y eso es todo.

¿Preguntas?

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.
Imagen de beto.bateria

El polimorfismo es el que le

El polimorfismo es el que le da POWER a la OOP.

Imagen de AlexSnake

Fácil de entender, difícil de digerir

+1 por tu post, es bastante entendible lo que explicas y muy fácil de entender, pero cuando lo quieres llevar a la práctica (al menos a mi me pasa) es cuando es difícil de digerir ya sea porque no estás acostumbrado a programar de esa forma o por que estas empezando a programar. Y ya que lo mencionaste tengo una duda, sí la clase   no tiene código en su método, ¿podría ser una interfaz? Es decir ¿puedo hacer polimorfismo con interfaces?

Un poquitin de abstraccion

En este caso, veo tambien la importancia de resaltar que existe eso de las clases y metodos abstractos. En el ejemplo de oscar se pudo haber definido una interface pero tambien una clase abtracta que defina los metodos que deben de rellenarse para que la implementacion tenga un comportamiento particular.

Me explico:
 

Definimos una clase   que nos dice que tenemos un metodo abstracto   el cual, por ser abstracto lo debemos definir en la clase que herede a   para que de esa forma el comportamiento sea diferente de todas esas implementaciones del metodo salva()

  
Lo que menciono quedaria asi
 
Como estamos haciendo herencia de   debemos definir este metodo (con el mismo modificador de acceso, porque asi se definio en la clase abstracta... queda de tarea investigar el ¿por qué?) y dentro de la sobreescritura del metodo ahi es donde le damos la particularidad del comportamiento.

  
Si deseamos tener varias clases con los mismos metodos y que puedan ser declaradas bajo un mismo tipo, esta solución también es viable e incluye el concepto de polimorfismo. Dicho lo anterior entonces sabemos que podemos hacer esto:
 
  
  
Para el desarrollo de plugins se maneja mucho el uso de interfaces que va tambien implicito el polimorfismo... "practicamente" es lo mismo que abstraccion, tiene mas limitaciones su uso en definicion de propiedades y de modificadores de acceso, ¿a ver quien se avienta a complementar el ejemplo de Oscar usando interfaces?

Imagen de AlexSnake

ejemplo mas complejo

Polimorfismo: "Llamada a un Java / método virtual utilizando una referencia a una superclase más generalizado de un objeto real invoca el método en el objeto real (el más específicos de subclase), utilizando un bottom-up mecanismo de búsqueda". Noooo pues con estas definiciones si le voy a entendeeeer, al menos con esta definicion me hago mas bolas. y luego este ejemplo que encontre:
 

Sinceramente no entiendo si se hace las mismas operaciones en   y cuando se manda al metodo y se ejecuta  

No dudo que para muchos se les complique entenderlo, pero tambien a otros como yo pues si se nos dificulta y mas con este tipo de ejemplos.

Imagen de AlexSnake

Hablando de sobreescritura...

Hace unos días tenía que hacer un progressbar que se actualizara conforme un proceso iba avanzando y ezamudio me recomendó utilizar el StringWorker, que mejor ejemplo para ilustrar lo que java.daba.doo menciona ya que tu clase debe extender de la clase StringWorker y pasarle dos parámetros que puede ser de cualquier tipo,   y debe sobrescribir el método  , ¿no sé si eso también sea polimorfismo?

Imagen de beto.bateria

Yo te recomendaria usar

Yo te recomendaria usar interfaces, a excepcion de algunos casos en donde te recomendaria clases Abtractas:

 

 

Muy bueno, pero algo confuso para novatos

Cuando antes trataba de explicarle a alguien nuevo a la POO comenzaba con ejemplos cómo el que tú das. Al final siempre terminaban preguntándome: "Bueno, a fin de cuentas polimorfismo es..." y con una carota de: "WTFFFF?!?!?!?!?!".

A mi parecer una manera más sencilla de hacer entender el polimorfismo es la manera en que llamas a un mensaje...aunque hay diferencia de opiniones respecto de los operadores (hablando de Java) en si se pueden o no considerar cómo mensajes. Sin embargo ilustran de una manera el polimorfismo. Ejemplo:
 

Y lo vemos fácil, pues para cadenas el símbolo + es igual a decirle: "concatena", y para números es igual a decirle: "suma". Otro ejemplo de polimorfismo con este mismo símbolo es el uso de expresiones regulares (las cuales, un servidor no domina muy bien, de hacer una metida de pata corregirme por favor), en donde este mismo símbolo (+) sirve para indicar que debe haber uno o más dígitos de un carácter indicado.

Bueno, ya está esto bastante largo, hasta ahí lo dejo.

Excepto que + es un operador

Excepto que   es un operador en Java, así que no hay objetos involucrados. :(

Imagen de benek

Re: Muy bueno, pero algo confuso para novatos

Eso es sobrecarga, de operadores.

Re: Excepto que + es un operador

Cierto, quizás no aplica para Java. Esto lo podríamos ilustrar puramente cómo objetos en Ruby, Scala; en donde todo es un objeto. Sin embargo es una manera sencilla de explicarlo.