BotonMenu
BotonIndice

Visita : conoce3000.com
Paypal : https://www.paypal.com/donate/?hosted_button_id=XY8TZ3MGN64GE

PASCAL CON FREE PASCAL

PASCAL CON FREE PASCAL

PASCAL CON FREE PASCAL


12. INTRODUCCIÓN A LA PROGRAMACIÓN ORIENTADA A OBJETOS III.
12.5. MÉTODOS DE MENSAJES.
12. INTRODUCCIÓN A LA PROGRAMACIÓN ORIENTADA A OBJETOS III.
12.5. MÉTODOS DE MENSAJES.
12. INTRODUCCIÓN A LA PROGRAMACIÓN ORIENTADA A OBJETOS III.
12.5. MÉTODOS DE MENSAJES.

SIGUIENTE

SIGUIENTE

SIGUIENTE


‒ Métodos de mensajes.

Los métodos a mensajes son punteros guardados en un área especial correspondiente a la clase que los implementa, los métodos de mensajes han sido diseñados especialmente para ser usados con funciones que devuelven una respuesta (callback functions), y que son usados ampliamente con herramientas de desarrollo de interfaces Gráficas de usuario (GUI) como son GTK y Win32 o Win64.

Los métodos de mensajes también se usan para implementar Eventos, ya que un método de mensaje puede ser la respuesta a un evento. La diferencia entre la implementación de eventos con punteros de métodos y métodos de mensaje, está en como se implementa los métodos de respuesta a los eventos. Cuando se usan punteros a métodos las respuestas a un evento se implementan generalmente en la clase contenedora y cuando se implementa con métodos de mensajes los métodos de respuesta se implementa haciendo una herencia de la clase que implementa sus eventos.

Para implementar un método de mensaje es suficiente colocar al final del método la palabra reservada message y seguido un número o una cadena de caracteres que identificará al método de mensajes. El evento será el número o cadena de caracteres que identifica al método de mensaje y el método de respuesta será el método de mensaje. Un método de mensaje se puede declarar del siguiente modo:

Procedure Cambios(Var Msg:TMsg); Message 1; [B] ~ [P] o con cadena de caracteres
Procedure Cambios(Var Msg:TMsg); Message 'EvCambios'; [B] ~ [P] Todos los métodos de mensajes son virtuales por defecto, lo que nos permite sobre escribirlo más adelante sin necesidad de las palabras reservadas virtual y override.

Además que todo método de mensaje debe tener como mínimo un parámetro que puede ser con tipo o sin tipo, pero lo más común es usar un registro en donde el primer campo debe ser de tipo Cardinal o una cadena de caracteres con un máximo de 255. TMsg se declará de la siguiente forma:

TMsg=Record
   MSGID : Cardinal;
   Data : integer;
End;

o con cadena de caracteres

TMsg=Record
   MSGID : String;
   Data : integer;
End;

Después del MSGID, se pueden colocar otros campos que pueden variar según lo necesite el evento a ejecutar.

Para enviar un mensaje o activar un evento a un método de mensaje se hace uso del método Dispatch o DispatchStr, del siguiente modo:

mensaje.MSGID:=1;
mensaje.Data:=indice;
Dispatch(mensaje);

o con cadena de caracteres

mensaje.MSGID:='EvCambios';
mensaje.Data:=indice;
DispatchStr(mensaje);

A continuación se muestra un ejemplo de una lista de números reales, que es el mismo que se vio en el capitulo anterior, pero esta vez usando los métodos de mensaje que implementarán los métodos de respuesta.


Descargar
{$codepage utf8}
{$mode objfpc}
Unit ListaReales;
Interface
Type

  TMsg=Record
       MSGID : Cardinal;
         Data : integer;
  End;

  TListaReales = class
    private
     Elementos:array of double;

     Procedure Pon(indice:integer;r:double);
     Function Obt(indice:integer):double;

    public
     cantidad:integer;
     mensaje:TMsg;

       Constructor Crear(n:integer=100);
       Property Elemento[i:integer]:double read Obt write Pon;default;

     Procedure DefaultHandler(var M);override;
     Procedure Cambios(Var Msg:TMsg); Message 1;
  End;

Implementation

  Procedure TListaReales.Pon(indice:integer;r:double);
    Begin
      Elementos[indice]:=r;
      mensaje.MSGID:=1;
      mensaje.Data:=indice;
    Dispatch(mensaje);
    End;

 Function TListaReales.Obt(indice:integer):double;
    Begin
     Obt:=Elementos[indice]
    End;

 Constructor TListaReales.Crear(n:integer=100);
    Begin
      SetLength(Elementos,n);
      cantidad:=n
    End;

  Procedure TListaReales.DefaultHandler(var M);
    Begin
    End;

  Procedure TListaReales.Cambios(Var Msg:TMsg);
    Begin
    End;

End.
Código fuente 14: TListaReales con método de mensaje Cambios.
Descargar

En esta clase existe sólo un método de mensaje Cambios que será el mensaje de respuesta cada vez que el método Dispatch envie el mensaje, este será enviando cada vez que se asigne un elemento a la lista ya que este se ejecuta desde dentro del método Pon.

Por defecto el método Cambios es un método vació que no hace absolutamente nada ya que este será reemplazado por otro cuando se herede la lista por otra clase.

A continuación el programa que hace uso de la lista de reales, en ella se puede observar que la clase TlistaFrecuencias hereda métodos y atributos de la clase TlistaReales, para sobreescribir el método de mensaje Cambios, que se usará para calcular las frecuencias.


Descargar
{$codepage utf8}
{$mode objfpc}
Uses ListaReales03;
Type
  TListaFrecuencias=class(TListaReales)
    Total:double;
    Procedure Cambios(Var Msg:TMsg); Message 1;
  End;

  TTablaFrecuencias = class
    class var
      i:longint;
    var

    ni,hi:TListaFrecuencias;
    NiMenorQ:TListaReales; //Con esto evitamos que sume un total que no es necesario
    cantidad:longint;

    Constructor Crear(n:longint);
    Procedure Lectura;
    Procedure Calculos;
    Procedure Mostrar;
  End;

  Constructor TTablaFrecuencias.Crear(n:longint);
   Begin
     ni:=TListaFrecuencias.Crear(n);
     hi:=TListaFrecuencias.Crear(n);
     NiMenorQ:=TListaFrecuencias.Crear(n);
     cantidad:=n;
   End;

  Procedure TTablaFrecuencias.Lectura;
   Var aux:double;
   Begin
    for i:=0 to  cantidad-1 do
      Begin
       Write('ni[',i,'] ');
       readln(aux);
       //Cada vez que se asigna una frecuencia absoluta se ejecuta el método MensajeCambios
       ni[i]:=aux;
      End;
   End;

  Procedure TTablaFrecuencias.Calculos;
   Begin

    //Frecuencia Relativa hi
    //Cada vez que se asigna una frecuencia relativa se ejecuta el método MensajeCambios
    for i:= 0 to cantidad-1 do hi[i]:=ni[i]/ni.Total;
    //Frecuencia Absoluta Acumulada Menor Que Ni
    NiMenorQ[0]:=ni[0];
    for i:=1 to cantidad-1 do  NiMenorQ[i]:=NiMenorQ[i-1]+ni[i];
   End;

  Procedure TTablaFrecuencias.Mostrar;
   Begin
     Writeln('        ni        hi        Ni');
     for i:=0 to cantidad-1 do
       Writeln(' ',ni[i]:10:2,hi[i]:10:2,NiMenorQ[i]:10:2);
     Writeln;
     Writeln('Total ',ni.Total:5:2,hi.Total:10:2)
   End;

   Procedure TListaFrecuencias.Cambios(Var Msg:TMsg);
    Begin
      Total:=Total+Elemento[Msg.Data];
    End;

Var TablaFrecuencias:TTablaFrecuencias;
    n:longint;
Begin
  Write('Ingrese numero de datos : ');readln(n);
  TablaFrecuencias:=TTablaFrecuencias.Crear(n);
  TablaFrecuencias.Lectura;
  TablaFrecuencias.Calculos;
  TablaFrecuencias.Mostrar
End.
Código fuente 15: Ejemplo del uso del método de mensaje Cambios.
Descargar

El uso de esta técnica se recomienda cuando se tenga que implementar eventos en donde todos los objetos ofrezcan una misma respuesta a un evento, y el puntero a métodos se usa generalmente cuando los objetos ofrezcan una respuesta distinta a un mismo evento. Es por eso que esta técnica es más usado en la implementación de interfaces Gráficas de usuario (GUI) como son GTK y Win32 o Win64.




SIGUIENTE
SIGUIENTE
SIGUIENTE


 
‒ Comentarios y sugerencias.

Agradezco de antemano, todo comentario, sugerencia, y donativo a través de , que ayude a mejorar los contenidos educativos de Conoce 3000. Además, cualquier pregunta o duda que tengas lo puedes hacer por este medio. Pero, todo contenido que pueda resultar ofensivo, malicioso, racista, sexista, discriminatorio, obsceno, vulgar será eliminado. Para clases particulares contactame por whatsapp al 📲 (+51) 999 264 073








PORTADA |  INTERESANTE |  APUNTES |  LIBROS |  GALERIA


Creative Commons License


Todos los textos, imágenes y videos de Conoce3000 estan colocados bajo una licencia : Creative Commons Reconocimiento-NoComercial 3.0 Unported License.