Polimorfismo en Java: Programación orientada a objetos

Cuando hablamos de polimorfismo no es que nos hemos vuelto locos. Todos saben que las personas que nos dedicamos al desarrollo de software, tenemos un lenguaje propio y no es que un ser procedente del espacio exterior y congelado por miles de años en la Antártida hubiera vuelto a la vida. No, no hablamos de ninguna película de miedo de los 80 sino de un concepto que por su utilidad debería estar en el ABC de cualquier libro de programación.

En programación orientada a objetos, polimorfismo es la capacidad que tienen los objetos de una clase en ofrecer respuesta distinta e independiente en función de los parámetros (diferentes implementaciones) utilizados durante su invocación. Dicho de otro modo el objeto como entidad puede contener valores de diferentes tipos durante la ejecución del programa.

En JAVA el término polimorfismo también suele definirse como ‘Sobrecarga de parámetros’, que así de pronto no suena tan divertido pero como veremos más adelante induce a cierta confusión. En realidad suele confundirse con el tipo de poliformismo más común, pero no es del todo exacto usar esta denominación.

Un ejemplo clásico de poliformismo es el siguiente. Podemos crear dos clases distintas: Gato y Perro, que heredan de la superclase Animal. La clase Animal tiene el método abstracto makesound() que se implementa de forma distinta en cada una de las subclases (gatos y perros suenan de forma distinta). Entonces, un tercer objeto puede enviar el mensaje de hacer sonido a un grupo de objetos Gato y Perro por medio de una variable de referencia de clase Animal, haciendo así un uso polimórfico de dichos objetos respecto del mensaje mover.

class Animal {
  public void makeSound() {
    System.out.println("Grr...");
  }
}
class Cat extends Animal {
  public void makeSound() {
    System.out.println("Meow");
  }
}
class Dog extends Animal {
  public void makeSound() {
    System.out.println("Woof");
  }
}

Como todos los objetos Gato y Perro son objetos Animales, podemos hacer lo siguiente

public static void main(String[ ] args) {
  Animal a = new Dog();
  Animal b = new Cat();
}

Creamos dos variables de referencia de tipo Animal y las apuntamos a los objetos Gato y Perro. Ahora, podemos llamar a los métodos makeSound().

a.makeSound();
//Outputs "Woof"

b.makeSound();
//Outputs "Meow"

Como decía el polimorfismo, que se refiere a la idea de "tener muchas formas", ocurre cuando hay una jerarquía de clases relacionadas entre sí a través de la herencia y este es un buen ejemplo.

Por lo general diremos que existen 3 tipos de polimorfismo:

  • Sobrecarga: El más conocido y se aplica cuando existen funciones con el mismo nombre en clases que son completamente independientes una de la otra.
  • Paramétrico: Existen funciones con el mismo nombre pero se usan diferentes parámetros (nombre o tipo). Se selecciona el método dependiendo del tipo de datos que se envíe.
  • Inclusión: Es cuando se puede llamar a un método sin tener que conocer su tipo, así no se toma en cuenta los detalles de las clases especializadas, utilizando una interfaz común.

Diferencias entre polimorfismo y sobrecarga

El polimorfismo presenta unas claras ventajas aplicado desde las interfaces, ya que nos permite crear nuevos tipos sin necesidad de modificar las clases ya existentes. Basta con recompilar todo el código que incluye los nuevos tipos añadidos sin retocar la clase anteriormente creada para añadir una nueva implementación lo que podría suponer una revisión completa de todo el código donde se instancia la clase.

Por contra, un método está sobrecargado si dentro de una clase existen dos o más declaraciones de dicho método con el mismo nombre pero con parámetros distintos, por lo que no hay que confundirlo con polimorfismo.

Esto puede parecer un poco confuso pero en definitiva el Polimorfismo consiste en redefinir un método de una clase padre en una clase hija. Mientras que sobrecarga es definir un nuevo método igual que otro viejo, pero cambiando el tipo o la cantidad de parámetros.

El compilador, viendo los parámetros, sabe a qué método llamar en función del parámetro que estás pasando. La sobrecarga se resuelve en tiempo de compilación utilizando los nombres de los métodos y los tipos de sus parámetros; el polimorfismo se resuelve en tiempo de ejecución del programa, esto es, mientras se ejecuta, en función de la clase a la que pertenece el objeto.

 

Guía de Posibilidades Profesionales en el Ecosistema de Java