AnteriorPosterior

Tema 16d. Programación orientada a objetos (4)

  Curso: Curso de Pascal, por Nacho Cabanes

Curso de Pascal. Tema 16.4: Más detalles...

Volviendo a lo que nos interesa.  Vamos a ver lo que ocurre si en vez de que el compilador determine a quién pertenecen X e Y (datos) le hacemos que tenga que determinar a quién pertenece un método como Escribe.

Para ello vamos a crear un nuevo método que va a asignar y escribir el texto en un sólo paso.  Nuestra nueva versión del programa queda:

 {--------------------------} 
 {  Ejemplo en Pascal:      } 
 {                          } 
 {    Cuarto ejemplo de     } 
 {    Prog. Orientada Obj.  } 
 {    OBJETOS4.PAS          } 
 {                          } 
 {  Este fuente procede de  } 
 {  CUPAS, curso de Pascal  } 
 {  por Nacho Cabanes       } 
 {                          } 
 {  Comprobado con:         } 
 {    - Free Pascal 2.2.0w  }
 {    - Turbo Pascal 7.0    } 
 {--------------------------}
 program Objetos4;                  { Nuestro cuarto programa en OOP }
 uses crt;                            { Usaremos "GotoXY" y TextAttr }
 type                                { Aquí definimos nuestro objeto }
   titulo = object 
     texto: string;                      { El texto que se escribirá } 
     x,y : byte;                                   { En qué posición } 
     procedure FijaCoords(nuevoX, nuevoY: byte);          { Pues eso } 
     procedure FijaTexto(mensaje: string);                    { Idem } 
     procedure Escribe;                          { Lo escribe, claro } 
     procedure AsignaYEscribe(nuevoTexto:string); 
   end;
  type 
   TituloColor = object( titulo ) 
     color: byte;                                  { El color, claro } 
     procedure FijaColores(pluma, fondo: byte);           { Pues eso } 
     procedure Escribe;               { Lo escribe de distinta forma } 
   end;
  type 
   TituloParpadeo = object( tituloColor ) 
     procedure FijaColores(pluma, fondo: byte);          { Pues eso } 
   end;
 var 
   T1: titulo;                      { Una variable de ese tipo } 
   T2: tituloColor;                 { Y otra del otro ;-)  } 
   T3: tituloParpadeo;              { Y el que queda }
 { --- Desarrollo del objeto Titulo --- }
 procedure titulo.FijaCoords(nuevoX, nuevoY: byte); 
 begin                                 { Definimos el procedimiento: } 
   x := nuevoX;                          { Actualiza las coordenadas } 
   y := nuevoY; 
 end;
 procedure titulo.FijaTexto(mensaje: string); 
 begin                                          { Actualiza el texto } 
   Texto := Mensaje; 
 end;
 procedure titulo.Escribe; 
 begin                                           { Muestra el título } 
   Gotoxy(X,Y); 
   Write(Texto); 
 end;
 procedure titulo.AsignaYEscribe(nuevoTexto:string); 
 begin 
   FijaTexto(NuevoTexto); 
   Escribe; 
 end;
 { --- Métodos específicos de TituloColor --- }
 procedure tituloColor.FijaColores(pluma,fondo: byte); 
 begin                                 { Definimos el procedimiento: } 
   color := pluma + fondo*16;                   { Actualiza el color } 
 end;
 procedure tituloColor.Escribe; 
 begin                                           { Muestra el título } 
   textAttr := color; 
   Gotoxy(X,Y); 
   Write(Texto); 
 end;
 { --- Métodos específicos de TituloParpadeo --- }
 procedure tituloParpadeo.FijaColores(pluma,fondo: byte); 
 begin                                 { Definimos el procedimiento: } 
   color := pluma + fondo*16 + 128;             { Actualiza el color } 
 end;
 { -- Cuerpo del programa --}
 begin 
   ClrScr; 
   T1.FijaCoords(37,12); 
   T1.AsignaYEscribe('Hola'); 
   T2.FijaCoords(37,13); 
   T2.FijaColores(14,2); 
   T2.AsignaYEscribe('Adiós'); 
   T2.Escribe; 
   T3.FijaCoords(35,14); 
   T3.FijaColores(15,3); 
   T3.AsignaYEscribe('Y una más'); 
 end.
 

Aparentemente, todo bien, ¿verdad?  Hemos hecho lo mismo que antes: no hemos redefinido "AsignaYEscribe" porque no nos hace falta:

 procedure titulo.AsignaYEscribe(nuevoTexto:string);
 begin
   FijaTexto(NuevoTexto);
   Escribe;
 end;

Queremos dar ese valor al texto y escribir el título.  Pues sí, todo bien...  ¿o no?

Si lo ejecutais vereis que no: el título que corresponde a T3 no ha salido con los mismos colores de antes (blanco parpadeante sobre azul claro) sino con los que corresponden a T2 (amarillo sobre verde).

¿Por qué?

Veamos: ¿dónde está el Escribe de "TituloParpadeo"?  ¡No está!  Claro, si lo hemos heredado...  pero por ahí vienen los fallos...

Cuando el compilador ve que el método AsignaYEscribe llama a Escribe, enlaza cada AsignaEscribe con su Escribe correspondiente.  Pero para "TituloParpadeo" no existe Escribe, así que ¿qué hace?  Pues toma el más cercano, el de su padre, TítuloColor.

Como comprobación, podeis hacer que el programa termine así:

  T3.AsignaYEscribe('Y una más');   { Con métodos anidados }
  readln;                           { Esperamos que se pulse INTRO }
  T3.Escribe;                       { Y lo hacemos directamente }
end.

En cuanto pulsamos INTRO, ejecuta T3.Escribe, y éste ya sí que funciona bien.
 

Actualizado el: 08-07-2012 14:14

AnteriorPosterior