‒ Polimorfismo por sobre-escritura con enlace posterior.
Los métodos y constructores que hemos visto en todas las clases de los capítulos anteriores, se conocen como métodos y constructores estáticos, y se ejecutan con un enlace anterior o estático. Esto quiere decir que la dirección de memoria del método a ejecutar se establece cuando se compila el programa.
Lo contrario son los métodos y constructores virtuales o dinámicos, en donde la dirección de memoria del método o constructor a ejecutar se establece, sólo cuando se ejecuta el programa, es decir los métodos o constructores se ejecutan con un enlace posterior o dinámico. Para explicar estos conceptos veremos a continuación el siguiente ejemplo. Dadas las siguientes clases:
Las clases TClase01 y TClase02, tienen un método Poner en común, en donde el método Poner de la clase TClase02, sobre-escribe al método Poner de la clase TClase01. También existe un método Mostrar en la clase TClase01, este ejecuta el método Poner de la clase TClase01. Ahora el siguiente programa hace uso de las clases a través de los objetos C01 y C02.
Cuando ejecute el programa se mostrará dos veces el numero 9. Esto es debido a que el método Mostrar del objeto C01 ejecutará el método poner de la clase TClase01, lo cual es correcto ya que el objeto C01 es de la clase TClase01. Pero cuando ejecutamos el método Mostrar del objeto C02, esté hará lo mismo y ejecutará el método Poner de la clase TClase01, ignorando el método Poner sobrescrito, de la clase TClase02. Si queremos que el método mostrar de la clase TClase01, ejecute el método poner de la clase descendiente TClase02, podemos sobre-escribir el método mostrar en la clase TClase02, para cambiar su comportamiento. Pero existe otro modo de hacer que el método Mostrar de la clase TClase01, ejecute el método Poner correspondiente a determinada clase. Para ello se hace uso de los métodos virtuales o dinámicos.
Primero se declara cómo virtual el método poner de la clase TClase01, colocando la palabra reservada virtual después del nombre del método, y del mismo modo, se coloca la palabra reservada override, al método poner de la clase TClase02. A continuación las clases con los cambios indicados:
Ahora cuando, se compila y ejecuta el programa prueba.pp, se mostrarán los números 9 y 5. Gracias al enlace posterior, el método mostrar de la clase TClase01, podrá determinar que método poner se ejecutará, dependiendo de qué objeto lo esté ejecutando. A esto se le conoce como Polimorfismo por enlace posterior.
Siguiendo con el ejemplo de las clases TComplejo y TReal, se desea añadir el método cuadrado, que nos permitirá elevar al cuadrado el número complejo colocado en su parámetro, pero para ello primero debemos sobre-escribir el método multiplicar en la clase TReal. Esto debido a que el método multiplicación tal como está, realiza cálculos innecesarios cuando es un objeto de la clase TReal, Es decir, si un objeto es de la clase TReal entonces no es necesario que multipliquemos la parte imaginaria, ya que este siempre será cero.
Primero sobre-escribimos el método multiplicación en la clase TReal, el método sería el siguiente:
Procedure TReal.Multiplicacion(n:TComplejo);
Begin
PonReal(ObtReal*n.ObtReal)
End;
Luego implementamos el método cuadrado que es el siguiente:
Procedure TComplejo.Cuadrado(n:Tcomplejo);
Begin
PonReal(n.obtReal);
PonImag(n.ObtImag);
Multiplicacion(n)
End;
Cómo podemos observar, el método cuadrado hace uso del método Multiplicación de la clase TComplejo, con lo que si creamos un objeto de la clase TReal y usamos el método Cuadrado, este ejecutará el método de la clase TComplejo y no el de la clase TReal. Pero como ya se explicó anteriormente debemos hacer que los métodos Multiplicación de ambas clases usen el enlace posterior, con ayuda de las palabras reservadas virtual y override. A continuación las clases TComplejo y TReal con los cambios indicados:
Cuando una clase tiene un método virtual, se asume que las clases descendientes implementaran dicho método del modo adecuado. Pero a veces se desea que ese comportamiento no suceda, es decir sólo se desea sobrescribir el método de la clase padre y que cuando algún método de la clase padre ejecute, el método virtual entonces ejecute dicho método y no el sobre-escrito por la clase descendiente. En esos casos simplemente no se debe usar la palabra reservada override en el método que sobre-escribe el método virtual. Pero al no hacerlo cuando se compila la clase, el compilador nos mostrará un mensaje de advertencia en ingles: “Warning: An inherited method is hidden by … ”, que en español sería: “Cuidado: Un método heredado es escondido por ...”. Si queremos que no aparezca ese mensaje entonces el método que sobre-escribe el método virtual, se le debe colocar la palabra reservada reintroduce.
Última revisión: 28/10/2013.