Entendiendo el Polimorfismo en Java: Conceptos y Uso Práctico
El polimorfismo es la capacidad de un objeto para tomar múltiples formas. El uso más común en POO ocurre cuando una referencia de clase padre apunta a un objeto de clase hija.
Todo objeto Java es polimórfico porque pasa la prueba IS-A para su propio tipo y para Object.
Variables de Referencia y Polimorfismo
- Una variable de referencia tiene un tipo fijo (no cambia tras declararse).
- Puede reasignarse a otros objetos (si no es
final). - El tipo de la referencia determina qué métodos se pueden invocar.
- Puede referenciar cualquier objeto de su tipo declarado o subtipos.
Ejemplo: Múltiples Tipos de Referencia para un Objeto
interface Vegetarian {}
class Animal {}
class Deer extends Animal implements Vegetarian {}
Un objeto Deer ES-UN: Animal, Vegetarian, Deer, Object.
Deer d = new Deer();
Animal a = d;
Vegetarian v = d;
Object o = d;
Todas las referencias (d, a, v, o) apuntan al mismo objeto Deer en el heap.
Métodos Virtuales (Virtual Methods)
En Java, los métodos de instancia no final, no static, no private son virtuales por defecto. La invocación se resuelve en tiempo de ejecución según el objeto real (dispatch dinámico).
Ejemplo Completo: Employee y Salary
/* Employee.java */
public class Employee {
private String name, address;
private int number;
public Employee(String name, String address, int number) {
System.out.println("Construyendo Employee");
this.name = name; this.address = address; this.number = number;
}
public void mailCheck() {
System.out.println("Enviando cheque a " + name + " " + address);
}
// getters/setters...
}
/* Salary.java */
public class Salary extends Employee {
private double salary;
public Salary(String name, String address, int number, double salary) {
super(name, address, number);
this.salary = salary;
}
@Override
public void mailCheck() {
System.out.println("Dentro de mailCheck de Salary");
System.out.println("Enviando cheque a " + getName() + " con salario " + salary);
}
// getSalary, setSalary, computePay...
}
/* VirtualDemo.java */
public class VirtualDemo {
public static void main(String[] args) {
Salary s = new Salary("Mohd Mohtashim", "Ambehta, UP", 3, 3600.00);
Employee e = new Salary("John Adams", "Boston, MA", 2, 2400.00);
System.out.println("Llamada mailCheck con referencia Salary --");
s.mailCheck();
System.out.println("\nLlamada mailCheck con referencia Employee --");
e.mailCheck(); // ¡invoca Salary.mailCheck() en tiempo de ejecución!
}
}
Salida:
Construyendo Employee Construyendo Employee Llamada mailCheck con referencia Salary -- Dentro de mailCheck de Salary Enviando cheque a Mohd Mohtashim con salario 3600.0 Llamada mailCheck con referencia Employee -- Dentro de mailCheck de Salary Enviando cheque a John Adams con salario 2400.0
Análisis
s.mailCheck(): Compilador veSalary.mailCheck(); JVM ejecutaSalary.mailCheck().e.mailCheck(): Compilador veEmployee.mailCheck()(valida la llamada); JVM ejecutaSalary.mailCheck()porque el objeto real esSalary.
Este comportamiento se llama invocación de método virtual. Permite escribir código flexible que trabaja con la superclase pero ejecuta la lógica específica de la subclase.
Polimorfismo en la Práctica: Beneficios
- Extensibilidad: Añadir nuevas subclases sin modificar código que usa la superclase.
- Desacoplamiento: El código cliente depende de abstracciones (interfaces/superclases), no de implementaciones concretas.
- Sustitución de Liskov: Una subclase puede usarse donde se espera la superclase sin romper el comportamiento.
Polimorfismo con Interfaces
Las interfaces son la forma más pura de polimorfismo: definen qué se hace, no cómo.
interface Drawable { void draw(); }
class Circle implements Drawable { public void draw() { ... } }
class Rectangle implements Drawable { public void draw() { ... } }
public class Canvas {
public void render(Drawable d) { d.draw(); }
}
El método render acepta cualquier Drawable.
Java
- Dominar Operadores en Java: Tipos, Sintaxis y Ejemplos Prácticos
- Comentarios en Java: Tipos, Uso y Mejores Prácticas
- Dominar el Bucle for Mejorado en Java: Sintaxis, Ejemplos y Mejores Prácticas
- Dominar Strings en Java: Creación, Métodos y Mejores Prácticas
- Dominando interfaces en Java: Conceptos, implementación y mejores prácticas
- Dominando las clases internas anónimas en Java: Definición, sintaxis y ejemplos prácticos
- Dominando Try‑with‑Resources en Java: Gestión automática de recursos explicada
- Anotaciones en Java explicadas: Tipos, ubicación y ejemplos prácticos
- Aserciones en Java: Guía práctica para detectar bugs y asegurar fiabilidad del código
- Entendiendo Java Vector: Uso, Características y Comparación con ArrayList
- Entendiendo el Polimorfismo en Java: Conceptos y Uso Práctico