Esta característica permite definir distintos comportamientos para un método dependiendo de la clase sobre la que se realize la implementación. En todo momento tenemos un único medio de acceso, sin embargo se podrá acceder a métodos
distintos.
Veamos el siguiente ejemplo, en el que se define una clase forma de la que se heredan las clases círculo y cuadrado.
La clase forma define los métodos dibujar y borrar. En la definición de estos métodos se implementará el código común a todos los objetos de la clase. Sin embargo cuando definamos las clases hijas, círculo y cuadrado, será
necesario modificar estos métodos para adaptarlos a las nuevas subclases. El método de la clase padre implementa aquellas acciones comunes. Las clases hijas añaden las operaciones particulares que necesiten. Cuando utilicemos
los métodos de la clase forma no tendremos que hacer distinción entre cuadrados y círculos. Gracias al polimorfismo se ejecutará el método adecuado en función de la subclase a la que pertenezca el objeto.
En la declaración de una clase estamos definiendo el conjunto de métodos y campos que son accesibles desde fuera de una clase o lo que a menudo se denomina contrato de la clase. Este contrato determina cual va
a ser la funcionalidad de la clase. Pero cuando extendemos una clase para crear otra estamos ampliando este contrato añadiendo mas funcionalidades. Por tanto cuando creamos esa nueva clase hacemos uso de dos mecanismos. Por
un lado la herencia para reutilizar las partes comunes de la super-clase. Y por otro el polimorfismo, es decir el cambio en la forma en la que se implementa el contrato de la superclase. Como
vemos al escribir una subclase podemos sobreescribir el contrato añadiendo nuevas funcionalidades, pero no cambiarlo.
A la hora de implementar el polimorfismo tendremos dos mecanismos de los que echar mano para sobreescribir una clase: reemplazar la implementación de un método o añadir funcionalidades a un método.
Continuando con el ejemplo de Publicacion, habíamos definido dos subclases Libro y Revista, vamos a ver cómo se implementan estas subclases:
La superclase Publicacion implementaba un método llamado toString() que devolvía una cadena compuesta en base al identificador, título y autor de una publicación. Al sobreescribir el método se utiliza el código de la superclase
y se añade a la cadena el número de páginas.
Veamos ahora como afecta la sobrescritura a la subclase Revista:
En este caso vemos como se reemplaza completamente la implementación dada por la super-clase para el método toString(). Normalmente las revistas no son firmadas por un único autor, por tanto es un campo que no vamos a utilizar.
Es necesario reescribir completamente el método y añadirle la periodicidad de la revista, campo que sí es importante en este tipo de publicaciones.