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?
- OscarRyz's blog
- Inicie sesión o regístrese para enviar comentarios
El polimorfismo es el que le
El polimorfismo es el que le da POWER a la OOP.
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
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?
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.
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?
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. :(
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.