Difference between revisions of "Object Oriented Programming with Free Pascal and Lazarus/es"

From Lazarus wiki
Jump to navigationJump to search
Line 81: Line 81:
 
<div class="floatleft"> [[Image:lazarus.UnFormulario.png]] </div>&nbsp;&nbsp;&nbsp;Vamos a estudiar la creación de un sencillo formulario con un control para una aplicación en FreePascal y Lazarus.
 
<div class="floatleft"> [[Image:lazarus.UnFormulario.png]] </div>&nbsp;&nbsp;&nbsp;Vamos a estudiar la creación de un sencillo formulario con un control para una aplicación en FreePascal y Lazarus.
  
<div class="floatright"> [[Image:Lazarus_Inspector_Objetos_form.png]] </div>  
+
<div class="floatright"> [[Image:Lazarus_Inspector_Objetos_form.png]] </div>&nbsp;&nbsp;&nbsp;Al ejecutar el IDE de Lazarus, al programador se le presenta, en diseño, un formulario en blanco, dentro del cual se pueden situar diversos controles y objetos.
 
 
&nbsp;&nbsp;&nbsp;Al ejecutar el IDE de Lazarus, al programador se le presenta, en diseño, un formulario en blanco, dentro del cual se pueden situar diversos controles y objetos.
 
 
Note that the pre-made blank Form is already an Object, with its own properties such as position (Top and Left), size (Height and Width), colour, default font for adding text etc.
 
Note that the pre-made blank Form is already an Object, with its own properties such as position (Top and Left), size (Height and Width), colour, default font for adding text etc.
  

Revision as of 11:28, 28 July 2008

Template:Object Oriented Programming with FreePascal and Lazarus

Programación Orientada a Objetos con FreePascal y Lazarus

Introducción

   Hay muchas excelentes tutorías sobre Pascal, pero esta pretender iniciar sobre la Programación Orientada a Objetos, que es una extensión del Pascal estándar, ofrecida por Turbo-pascal, Delphi y FreePascal/Lazarus.

   Un Objeto es una extensión de la estructura registro del Pascal estándar.

   La programación estándar en modo texto de Pascal es, cómo las aplicaciones Unix tradicionales, buena para hacer cualquier tarea y que se haga muy bien. Pero esta tarea puede ser algo compleja y que ofrezca al usuario variado menú de opciones, pero sin embargo está limitado a obedecer ordenes que se escriben por el teclado y mostrar las respuestas en un terminal o impresora.

   Con el fin de proporcionar una interfaz gráfica de usuario (GUI), es habitual recurrir a algún tipo de programación orientada a objetos (a menudo haciendo uso de C, o alguna de sus variantes, o Visual Basic, o alguna de las variantes de OO de Pascal, como FreePascal con o sin Lazarus).

   En una interfaz gráfica de usuario (GUI) al usuario se le presenta una pantalla con un gran número de imágenes dispuestas en forma estructurada, que consta de un conjunto de herramientas o artefactos que están asociados con diversas acciones, tales como

  • seleccionar de un menú,
  • abrir o guardar archivos,
  • conectar a Internet,
  • realización de cálculos numéricos, etc.

   Del usuario se espera que mueva un ratón u otro tipo de puntero o herramienta de selección sobre la pantalla, para seleccionar las acciones que se realizarán en respuesta a un clic de ratón o la pulsación de una tecla.

   Si bien sistemas para realizar una compleja interfaz gráfica de usuario pueden ser escritos en Pascal estándar o cualquier otro lenguaje de programación, es mucho más fácil utilizar un sistema orientado a objeto s, en el que cada elemento gráfico en la pantalla tiene todas sus propiedades, procedimientos y funciones relacionadas con su utilización unidas juntas en una estructura común, en un objeto.

Objetos: una analogía con el mundo real

   Considera la analogía de una muestra de sangre recogida en un hospital o en la consulta del médico.

Análisis de sangre

   La muestra de sangre es ciertamente un objeto; se ha asociado a ella una gran cantidad de información, documentos y otros objetos físicos.

  • Tubo de muestra, del tipo adecuado a las pruebas que el médico quiere realizar.
  • Reglamento interno (o método, procedimiento de operación estándar) para dirigir a la enfermera o técnico en la recogida de la muestra.
    • qué tipo de tubo debe utilizar,
    • cómo debe procesar la muestra,
    • cómo almacenarla hasta que se envía al laboratorio.
  • Etiqueta en el tubo con detalles sobre
    • identificador de la muestra
    • datos del paciente, nombre, fecha de nacimiento,...
    • fecha y hora de toma de la muestra
    • pruebas solicitadas.
  • Formulario de solicitud que acompaña a la muestra al laborarorio, con datos como
    • Identificador de la muestra
    • Identificación del médico solicitante
    • que pruebas ha pedido el médico
    • información detallada sobre el paciente
    • el posible diagnóstico cuya confirmación que se busca.

   Una copia del formulario de solicitud se guarda en el historial del paciente y sirve para recordar al médico que debe tener los resultados en un tiempo adecuado.

  • En el laboratorio: Se usa una Metodología para determinar
    • la forma en que la muestra se analiza,
    • qué aparatos hay que utilizar,
    • Cómo se deben calibrar y manejar los aparatos,
    • cómo archivar los resultados, y el formato de los mismos,
    • remitir los informes al médico.

   Los resultados reales son un registro que utiliza el médico para ayudar al diagnóstico, y una copia de los mismos se archivo en el historial del paciente.

   La muestra física puede ser conservada para referencia, confirmación o nuevos ensayos, o será eliminada por algún medio adecuado; habrá un método regulado que describirá como hacer esto.

   EL médico no necesita explicar todos los detalles e instrucciones cada vez que se toma una muestra, de hecho puede tener muy poco conocimiento sobre cómo se procesa la muestra en el laboratorio. Los detalles de los diversos procesos son heredados de tomas de muestras y análisis previos. Habrá un plan genérico para toda la secuencia, y así podríamos pensar en la muestra de sangre, todos sus documentos y datos, y los métodos de proeceso subyacentes, como un objeto complejo.

   En la cabeza del médico, la muestra de sangre es identificada con los resultados, así como con las enfermeras y técnicos de laboratorio, el tubo, la etiqueta y las condiciones de almacenamiento, constituyendo todo ello una única entidad.

Otro ejemplo: automóvil

Si no le gusta la sangre, el mismo tipo de razonamiento puede aplicarse a un coche enviado a un taller para su reparación. Podría consistir en:

  • el vehículo
  • documentos en poder del propietario: registro o licencia (incluida la matrícula de un vehículo), los seguros, los recibos de compra, repuestos, reparaciones, etc.
  • la historia del consumo de combustible
  • los conductores autorizados a utilizar el vehículo, con los datos de su licencia
  • informes de otros servicios prestados por el taller
  • métodos o procedimientos que deben seguirse para el proceso de revisión y mantenimiento
  • métodos que deben seguirse para reparaciones no habituales, etc.
  • datos de facturación para el cliente

Programando un ejemplo

   ¡Ya está bien de ocuparse de ejemplos del mundo real! Es el momento de dedicarnos a nuestro propósito principal: programar en FreePascal.

lazarus.UnFormulario.png

   Vamos a estudiar la creación de un sencillo formulario con un control para una aplicación en FreePascal y Lazarus.

Lazarus Inspector Objetos form.png

   Al ejecutar el IDE de Lazarus, al programador se le presenta, en diseño, un formulario en blanco, dentro del cual se pueden situar diversos controles y objetos.

Note that the pre-made blank Form is already an Object, with its own properties such as position (Top and Left), size (Height and Width), colour, default font for adding text etc.

Usar un control

If a Button control is placed on the Form (type TButton), it will have its own series of properties, which can be examined in the Object Inspector window.

Several of the properties have names similar to those for the Form; this is because many properties are Inherited from some common Ancestor class, which lays out how properties are to be defined and handled by the descendant classes.

As well as properties, the Object Inspector offers a tab called Events, which gives access to Event Handlers which are methods instructing the application how to deal with things such as a mouse click on a button (OnClick) or some change in the position, size or other properties (OnChange).

The physical image of the Button on the Form, together with all its properties and Event Handler methods, should be regarded as a single entity or Object in Pascal.

lazarus.InspectorTButton.png
lazarus.UnFormularioConBoton.png
Source FormWithButton1.png

Object-Oriented Extensions to standard Pascal

The Pascal record structure is extended by defining an

Object

An Object is a special kind of record. The record contains all the fields that are declared in the object's definition (just like a conventional record), but now procedures and functions can be declared as if they were part of the record and are held as pointers to the methods associated with the object's type.

For example, an object could contain an array of real values, together with a Method for calculating the average.

Type
  Average = Object
    NumVal: Integer;
    Values: Array [1..200] of Real;
    Function Mean  : Real; { calculates the average value of the array }
  End;

Objects can ”inherit” fields and methods from ”parent” objects. This means that these fields and methods can be used as if they were included in the objects declared as a ”child” object.

Furthermore, a concept of visibility is introduced: fields, procedures and functions can be declared as public, protected or private. By default, fields and methods are public, and can be exported outside the current unit. Protected fields or methods are available only to objects descended from the current ancestor object. Fields or methods that are declared private are only accessible in the current unit: their scope is limited to the implementation of the current unit.

Class

Objects are not used very often by themselves in FreePascal and Lazarus; instead, Classes are used very widely. A Class is defined in almost the same way as an Object, but is a pointer to an Object rather than the Object itself. Technically, this means that the Class is allocated on the Heap of a program, whereas the Object is allocated on the Stack.

Here is a simple example of a typical Class declaration:

{-----------------------------------------}
{example of Class declaration from the LCL}
{-----------------------------------------}
 TPen = class(TFPCustomPen)
 private
   FColor: TColor;
   FPenHandleCached: boolean;
   FReference: TWSPenReference;
   procedure FreeReference;
   function GetHandle: HPEN;
   function GetReference: TWSPenReference;
   procedure ReferenceNeeded;
   procedure SetHandle(const Value: HPEN);
 protected
   procedure DoAllocateResources; override;
   procedure DoDeAllocateResources; override;
   procedure DoCopyProps(From: TFPCanvasHelper); override;
   procedure SetColor
        (const NewColor: TColor; const NewFPColor: TFPColor); virtual;
   procedure SetFPColor(const AValue: TFPColor); override;
   procedure SetColor(Value: TColor);
   procedure SetMode(Value: TPenMode); override;
   procedure SetStyle(Value: TPenStyle); override;
   procedure SetWidth(value: Integer); override;
 public
   constructor Create; override;
   destructor Destroy; override;
   procedure Assign(Source: TPersistent); override;
   property Handle: HPEN read GetHandle write SetHandle; deprecated;
   property Reference: TWSPenReference read GetReference;
 published
   property Color: TColor read FColor write SetColor default clBlack;
   property Mode default pmCopy;
   property Style default psSolid;
   property Width default 1;
 end;


Note that this class is defined as an instance of another parent or ancestor class (TFPCustomPen) from which it inherits all its properties and methods. It has some fields of its own, grouped under

  • private - this means that items defined here are only available or visible to other classes or procedures/function defined within the same program unit (this example is from Graphics, so any of the other classes such as TBitMap, TPicture etc in the same unit can use them). They are essentially local variables (eg FColor, FPenHandleCached) or locally used methods (GetHandle, SetHandle) but can be used or referred to in items declared in the protected or public sections.
  • protected - this means that items defined here are only available or visible to classes that are descended from this ancestor class, and inherit its properties or methods
  • public - this means that items defined here are available to any programming unit that includes the current unit in its Uses clause
  • published - is the same as a public section, but the compiler also generates type information that is needed for automatic streaming of these classes. Often the list of published items appear in the Object Inspector of Lazarus; if there is no published list, all the public fields usually appear in the Object Inspector.

Methods

A method is just like a standard procedure or function, but can have some additional directives.

Some of the methods defined above are labelled with the directive virtual; others are labelled with the override directive.

  • virtual means that the type or actual instance of a method is not known at compile-time, but is selected at run-time depending on what sub-program actually calls the method. It could be considered a place-holder in the definition of the class.
  • override means that at run-time the locally given definition can take the place of a definition inherited from an ancestor class, particularly if it was virtual. If you particularly want to use the method defined in the ancestor class, it is sometimes necessary to call it specifically with the inherited clause.

Methods with no virtual or override directive are static methods (the usual kind in Pascal). Those with a virtual or override directive are dynamic.

Special instances of methods are:

  • create - a constructor for a class, which takes care of allocating memory, collecting together all the information needed and configuring/initializing the various properties.
  • destroy - a destructor for a class, which removes all the parts of the class from the system in an orderly and logical way, and returns all its resources for the system to re-use.

Properties

Properties are just like ordinary fields in a conventional Pascal record, but they can have read and/or write specifiers.

  • read specifier is a field, or a function that returns a result of the correct type for the property. In the example above, the property Color has a read specifier FColor, which is a local variable containing the value to be used. If a property has a read but no write specifier, it is read-only.
  • write specifier is a field, or a procedure that will store the value of the property in a specific location. In the example above, Color has a write specifier SetColor that is a procedure (defined in the protected section) for writing the color value to some specified location. If a property has a write but no read specifier, it is write-only.
  • default - note that it is possible to set a default value for a property. For example, Color here is given the default value clBlack, or black, at the time of creation. It could subsequently be given a different value, by a programming assignment statement, or in the Object Inspector.


Más información

   Este artículo sólo ha arañado la superficie del tema. Para más detalles, se recomienda encarecidamente leer los manuales de FreePascal , especialmente los capítulos 4 Objetos y 5 Clases.