Bienvenidos sean a este post, el polimorfismo es la habilidad de un objeto de poder adoptar muchas formas, su uso mas habitual en OOP (Programacion Orientada a Objetos por sus siglas en ingles) es cuando una referencia de clase padre es usado como referencia para un objeto de la clase hija.
En Java se considera que si un objeto pasa mas de una prueba ES-UN como polimorfico, todos los objetos son polimorficos desde que un objeto pasa la prueba de ES-UN para su propio tipo y el objeto de la clase, es importante aclrara que de la unica forma que se puede acceder a un objeto es a traves de una variable de referencia, esta variable puede ser de un solo tipo y una vez declarada no puede ser cambiada.
Las variables de referencia pueden ser reasignadas a otro objeto siempre y cuando este no este declarado como final, este tipo de variable determinara que metodos puede invocar en el objeto, este tipo de variable puede referir a cualquier objeto de su tipo declarado o a cualquier subtipo de un tipo declarado, y por ultimo estas pueden ser declaradas como una clase o un tipo de interfaz.
Veamos un simple ejemplo para entenderlo un poco mejor:
public interface Vegetariano {}
public class Animal{}
public class Venado extends Animal implements Vegetariano {}
En este caso la clase Venado es la polimorfica porque la misma recibe varias herencias, hagamos la siguiente prueba de consideraciones:
- Venado ES UN Animal
- Venado ES UN Vegetariano
- Venado ES UN Venado
- Venado ES UN Objeto
Como pueden ver al hacer la prueba de ES-UN consideramos a las mismas como verdaderas, con el ejemplo anterior veamos algunas declaraciones legales:
Venado v = new Venado();
Animal a = v;
Vegetariano ve = v;
Objeto o = v;
Todas las variables en este caso estan referenciadas al mismo objeto Venado ubicado en el heap, pasemos al siguiente aspecto: Metodos virtuales.
En el post anterior hablamos sobre anulacion (override) y vimos como basicamente un metodo anulado esta escondido en la clase padre pero nosotros podemos invocarlo por medio de la palabra super como vimos en el ultimo ejemplo, en el siguiente ejemplo veremos como sacar ventaja de la anulacion de metodos para polimorfismo. Para este ejemplo vamos a crear tres archivos, los dos primeros van a ser clases para crear un empleado y luego manejar el salario y la ultima va a ser el programa, comencemos con la primera clase:
Trabajador.java
public class Trabajador
{
private String nombre;
private String direccion;
private int numero;
public Trabajador(String nombre, String direccion, int numero)
{
System.out.println("Construyendo el empleado");
this.nombre = nombre;
this.direccion = direccion;
this.numero = numero;
}
public void chequeoMail()
{
System.out.println("Enviando un mail para chequear "
+ this.name + " " + this.direccion);
}
public String toString()
{
return nombre + " " + direccion + " " + numero;
}
public String getNombre()
{
return nombre;
}
public String getDireccion()
{
return direccion;
}
public void setAddress(String nueva)
{
direccion = nueva;
}
public int getNumero()
{
return numero;
}
}
Esta clase se encargara de crear a nuestro Trabajador, en el constructor podremos enviar los datos de nombre, direccion y numero del mismo, tambien nos mostrara un mensaje cuando ingrese al mismo, despues tendremos varios metodos, uno llamado toString que nos devuelve los tres datos, getNombre() para devolver el valor de nombre, getDireccion() nos devuelve la direccion, setAddress() se encarga de cambiar la direccion con una nueva, y por ultimo getNumero() nos devuelve el valor de numero, pasemos a la siguiente clase:
Salario.java
public class Salario extends Trabajador
{
private double salario;
public Salario(String nombre, String direccion, int numero,
double salario)
{
super(nombre, direccion, numero);
setSalario(salario);
}
public void chequeoMail()
{
System.out.println("Dentro de chequeoMail en la clase"
+ " Salario");
System.out.println("Enviando cheque por correo a "
+ getNombre() + " con el salario " + salario);
}
public double getSalario()
{
return salario;
}
public void setSalario(double nuevo)
{
if(nuevo >= 0.0)
salario = nuevo;
}
public double pagoComputado()
{
System.out.println("Computando la paga de salario para "
+ getNombre());
return salario/52;
}
}
En esta clase administraremos el salario de cada Trabajador, y esta a su vez sera heredera de Trabajador, en este caso tendremos un constructor donde recibira los tres datos del constructor de la clase anterior y por ultimo el salario del Trabajador, en el constructor enviaremos los tres primeros datos a la clase anterior por medio de la palabra super y luego llamamos a setSalario para asignar el nuevo valor a salario. nuestro siguiente metodo sera chequeoMail() y este anulara al de la clase padre donde nos mostrara otro mensaje y traera el nombre del empleado por medio del metodo getNombre() de la clase Trabajador, este metodo es heredado, y luego mostrara el valor asignado a salario, el sisguiente metodo (getSalario) nos devuelve el valor de salario, luego esta setSalario() que se encargara de asignar un nuevo valor siempre y cuando nuevo sea mayor o igual a 0.0, por ultimo tendremos el metodo pagoComputado() donde nos mostrara un mensaje donde nos traera por medio del metodo getNombre() y luego devolvera el valor de salario divido 52, pasemos a nuestra ultima clase:
VirtualDemo.java
public class VirtualDemo
{
public static void main(String[] args)
{
Salario s = new Salario("Martin Miranda", "M. sosa",333,10000.00);
Trabajador t = new Salario("Enzo Tortore", "Gral. Paz",900,9000.00);
System.out.println("Llamando a chequeoMail usando referencia de Salario --");
s.chequeoMail();
System.out.println("LLamada a chequeoMail usando referencia de Trabajador --");
t.chequeoMail();
}
}
Esta clase se encargara de crear dos objetos, uno referenciado a la clase Salario y otro a la clase Trabajador, en ambos casos utilizaremos el constructor de la clase Salario para crear el objeto de este tipo, en ambos casos enviaremos los datos de los dos trabajadores, luego llamaremos al metodo chequeoMail() de la clase Salario y despues al mismo metodo de la clase Trabajador, si lo compilamos y ejecutamos obtendremos esta salida:
tinchicus@dbn001vrt:~/programacion/java/program$ java VirtualDemo Construyendo el empleado Construyendo el empleado Llamando a chequeoMail usando referencia de Salario -- Dentro de chequeoMail en la clase Salario Enviando cheque por correo a Martin Miranda con el salario 10000.0 LLamada a chequeoMail usando referencia de Trabajador -- Dentro de chequeoMail en la clase Salario Enviando cheque por correo a Enzo Tortore con el salario 9000.0 tinchicus@dbn001vrt:~/programacion/java/program$
Como pueden ver se ejecuto correctamente nuestro programa, creando los Trabajadores, con sus respectivos datos, tambien obtuvimos los nombres por medio de un metodo heredado, y si bien utilizamos referencias distintas e internamente usaron sus respectivos metodos chequeoMail() pero como vemos en la salida utilizo el metodo unicamente de la clase Salario. En el momento de compilacion, chequeoMail() en Trabajador es usado para chequear la declaracion, sin embargo en el momento de ejecucion JVM (Java Virtual Machine) invocara al metodo chequeoMail() pero de la clase Salario. Esta conducta es referenciada como invocacion de metodos virtuales y estos metodos son referenciados como metodos virtuales, en el momento de ejecucion los metodos anulados son los invocados no importa el tipo de data que se use como referencia en el codigo fuente al momento de compilacion.
En resumen, hoy hemos visto que es y para que sirve el polimorfismo, la forma de chequear si cumplimos con todo, hemos visto un ejemplo de como hacerlo trabajar, hemos visto metodos virtuales, y hablado un poco sobre ellos, espero les haya sido util sigueme en tumblr, Twitter o Facebook para recibir una notificacion cada vez que subo un nuevo post en este blog, nos vemos en el proximo post.
Tengo un Patreon donde podes acceder de manera exclusiva a material para este blog antes de ser publicado, sigue los pasos del link para saber como.


Tambien podes donar
Es para mantenimiento del sitio, gracias!
$1.50