Pascal - Orientado a objetos

Podemos imaginar nuestro universo hecho de diferentes objetos como el sol, la tierra, la luna, etc. De manera similar, podemos imaginar nuestro auto hecho de diferentes objetos como volante, dirección, engranaje, etc. De la misma manera, existen conceptos de programación orientados a objetos, que asumir todo como un objeto e implementar un software utilizando diferentes objetos. En Pascal, hay dos tipos de datos estructurales que se utilizan para implementar un objeto del mundo real:

  • Tipos de objetos
  • Tipos de clases

Conceptos orientados a objetos

Antes de entrar en detalle, definamos términos importantes de Pascal relacionados con Pascal orientado a objetos.

  • Object- Un objeto es un tipo especial de registro que contiene campos como un registro; sin embargo, a diferencia de los registros, los objetos contienen procedimientos y funciones como parte del objeto. Estos procedimientos y funciones se mantienen como punteros a los métodos asociados con el tipo de objeto.

  • Class- Una clase se define casi de la misma manera que un objeto, pero hay una diferencia en la forma en que se crean. La clase se asigna en el montón de un programa, mientras que el objeto se asigna en la pila. Es un puntero al objeto, no al objeto en sí.

  • Instantiation of a class- La instanciación significa crear una variable de ese tipo de clase. Dado que una clase es solo un puntero, cuando se declara una variable de un tipo de clase, hay memoria asignada solo para el puntero, no para todo el objeto. Solo cuando se crea una instancia utilizando uno de sus constructores, se asigna memoria para el objeto. Las instancias de una clase también se denominan 'objetos', pero no las confunda con Object Pascal Objects. En este tutorial, escribiremos 'Objeto' para Pascal Objects y 'objeto' para el objeto conceptual o instancia de clase.

  • Member Variables - Son las variables definidas dentro de una Clase o un Objeto.

  • Member Functions - Estas son las funciones o procedimientos definidos dentro de una Clase o un Objeto y se utilizan para acceder a los datos del objeto.

  • Visibility of Members- Los miembros de un objeto o clase también se denominan campos. Estos campos tienen diferentes visibilidades. La visibilidad se refiere a la accesibilidad de los miembros, es decir, exactamente dónde serán accesibles estos miembros. Los objetos tienen tres niveles de visibilidad: público, privado y protegido. Las clases tienen cinco tipos de visibilidad: pública, privada, estrictamente privada, protegida y publicada. Discutiremos la visibilidad en detalle.

  • Inheritance- Cuando una clase se define heredando las funcionalidades existentes de una clase principal, se dice que es heredada. Aquí la clase secundaria heredará todas o algunas funciones miembro y variables de una clase principal. Los objetos también se pueden heredar.

  • Parent Class- Una clase heredada por otra clase. Esto también se denomina clase base o superclase.

  • Child Class- Una clase que hereda de otra clase. Esto también se denomina subclase o clase derivada.

  • Polymorphism- Este es un concepto orientado a objetos donde la misma función puede usarse para diferentes propósitos. Por ejemplo, el nombre de la función seguirá siendo el mismo, pero puede necesitar un número diferente de argumentos y puede realizar diferentes tareas. Las clases de Pascal implementan polimorfismo. Los objetos no implementan polimorfismo.

  • Overloading- Es un tipo de polimorfismo en el que algunos o todos los operadores tienen diferentes implementaciones según los tipos de sus argumentos. De manera similar, las funciones también pueden sobrecargarse con una implementación diferente. Las clases Pascal implementan la sobrecarga, pero los Objetos no.

  • Data Abstraction - Cualquier representación de datos en la que los detalles de implementación estén ocultos (abstraídos).

  • Encapsulation - Se refiere a un concepto en el que encapsulamos todos los datos y funciones miembro para formar un objeto.

  • Constructor - Se refiere a un tipo especial de función que se llamará automáticamente siempre que haya una formación de objeto de una clase o un Objeto.

  • Destructor - Se refiere a un tipo especial de función que se llamará automáticamente cada vez que un Objeto o Clase se elimine o salga de su alcance.

Definición de objetos Pascal

Un objeto se declara mediante la declaración de tipo. La forma general de una declaración de objeto es la siguiente:

type object-identifier = object  
   private
   field1 : field-type;  
   field2 : field-type;  
   ...
   public
   procedure proc1;  
   function f1(): function-type;
   end;  
var objectvar : object-identifier;

Definamos un objeto Rectangle que tiene dos miembros de datos de tipo entero: length y width y algunas funciones miembro para manipular estos miembros de datos y un procedimiento para dibujar el rectángulo.

type 
   Rectangle = object  
   private  
      length, width: integer; 
   
   public  
      constructor init;  
      destructor done;  
      
      procedure setlength(l: inteter);  
      function getlength(): integer;  
      
      procedure setwidth(w: integer);  
      function getwidth(): integer;  
      
      procedure draw;
end;
var
   r1: Rectangle;
   pr1: ^Rectangle;

Después de crear sus objetos, podrá llamar a funciones miembro relacionadas con ese objeto. Una función miembro solo podrá procesar la variable miembro del objeto relacionado.

El siguiente ejemplo muestra cómo establecer longitudes y anchos para dos objetos rectangulares y dibujarlos llamando a las funciones miembro.

r1.setlength(3);
r1.setwidth(7);

writeln(' Draw a rectangle: ', r1.getlength(), ' by ' , r1.getwidth());
r1.draw;
new(pr1);
pr1^.setlength(5);
pr1^.setwidth(4);

writeln(' Draw a rectangle: ', pr1^.getlength(), ' by ' ,pr1^.getwidth());
pr1^.draw;
dispose(pr1);

A continuación se muestra un ejemplo completo para mostrar cómo usar objetos en Pascal:

program exObjects;
type 
   Rectangle = object  
   private  
      length, width: integer; 
   
   public  
      procedure setlength(l: integer);
      function getlength(): integer;  
      
      procedure setwidth(w: integer);  
      function getwidth(): integer;  
      
      procedure draw;
end;
var
   r1: Rectangle;
   pr1: ^Rectangle;

procedure Rectangle.setlength(l: integer);
begin
   length := l;
end;

procedure Rectangle.setwidth(w: integer);
begin
   width :=w;
end;

function Rectangle.getlength(): integer;  
begin
   getlength := length;
end;

function Rectangle.getwidth(): integer;  
begin
   getwidth := width;
end;

procedure Rectangle.draw;
var 
   i, j: integer;
begin
   for i:= 1 to length do
   begin
     for j:= 1 to width do
        write(' * ');
     writeln;
   end;
end;

begin
   r1.setlength(3);
   r1.setwidth(7);
   
   writeln('Draw a rectangle:', r1.getlength(), ' by ' , r1.getwidth());
   r1.draw;
   new(pr1);
   pr1^.setlength(5);
   pr1^.setwidth(4);
   
   writeln('Draw a rectangle:', pr1^.getlength(), ' by ' ,pr1^.getwidth());
   pr1^.draw;
   dispose(pr1);
end.

Cuando se compila y ejecuta el código anterior, produce el siguiente resultado:

Draw a rectangle: 3 by 7
* * * * * * *
* * * * * * *
* * * * * * *
Draw a rectangle: 5 by 4
* * * *
* * * *
* * * *
* * * *
* * * *

Visibilidad de los miembros del objeto

La visibilidad indica la accesibilidad de los miembros del objeto. Los miembros de objeto Pascal tienen tres tipos de visibilidad:

No Señor Visibilidad y accesibilidad
1

Public

Los miembros pueden ser utilizados por otras unidades fuera de la unidad del programa.

2

Private

Los miembros solo son accesibles en la unidad actual.

3

Protected

Los miembros están disponibles solo para objetos descendientes del objeto principal.

De forma predeterminada, los campos y métodos de un objeto son públicos y se exportan fuera de la unidad actual.

Constructores y destructores para objetos Pascal -

Constructorsson tipos especiales de métodos, que se llaman automáticamente cada vez que se crea un objeto. Creas un constructor en Pascal simplemente declarando un método con una palabra clave constructor. Convencionalmente, el nombre del método es Init, sin embargo, puede proporcionar cualquier identificador válido propio. Puede pasar tantos argumentos como desee a la función constructora.

Destructorsson métodos que se llaman durante la destrucción del objeto. Los métodos destructores destruyen cualquier asignación de memoria creada por los constructores.

El siguiente ejemplo proporcionará un constructor y un destructor para la clase Rectangle que inicializará la longitud y el ancho del rectángulo en el momento de la creación del objeto y lo destruirá cuando salga del alcance.

program exObjects;
type 
   Rectangle = object  
   private  
      length, width: integer; 
   public  
      constructor init(l, w: integer);
      destructor done;
      
      procedure setlength(l: integer);
      function getlength(): integer;  
      
      procedure setwidth(w: integer);  
      function getwidth(): integer;  
      
      procedure draw;
end;

var
   r1: Rectangle;
   pr1: ^Rectangle;

constructor Rectangle.init(l, w: integer);
begin
   length := l;
   width := w;
end;

destructor Rectangle.done;
begin
   writeln(' Desctructor Called');
end; 

procedure Rectangle.setlength(l: integer);
begin
   length := l;
end;

procedure Rectangle.setwidth(w: integer);
begin
   width :=w;
end;

function Rectangle.getlength(): integer;  
begin
   getlength := length;
end;

function Rectangle.getwidth(): integer;  
begin
   getwidth := width;
end;

procedure Rectangle.draw;
var 
   i, j: integer;
begin
   for i:= 1 to length do
   begin
      for j:= 1 to width do
         write(' * ');
      writeln;
   end;
end;

begin
   r1.init(3, 7);
   writeln('Draw a rectangle:', r1.getlength(), ' by ' , r1.getwidth());
   r1.draw;
   new(pr1, init(5, 4));
   
   writeln('Draw a rectangle:', pr1^.getlength(), ' by ',pr1^.getwidth());
   pr1^.draw;
   pr1^.init(7, 9);
   
   writeln('Draw a rectangle:', pr1^.getlength(), ' by ' ,pr1^.getwidth());
   pr1^.draw;
   dispose(pr1);
   r1.done;
end.

Cuando se compila y ejecuta el código anterior, produce el siguiente resultado:

Draw a rectangle: 3 by 7
* * * * * * *
* * * * * * *
* * * * * * *
Draw a rectangle: 5 by 4
* * * *
* * * *
* * * *
* * * *
* * * *
Draw a rectangle: 7 by 9
* * * * * * * * *
* * * * * * * * *
* * * * * * * * *
* * * * * * * * *
* * * * * * * * *
* * * * * * * * *
* * * * * * * * *
Destructor Called

Herencia de objetos Pascal

Los objetos Pascal pueden heredar opcionalmente de un objeto padre. El siguiente programa ilustra la herencia en Pascal Objects. Creemos otro objeto llamadoTableTop, que hereda del objeto Rectangle.

program exObjects;
type 
   Rectangle = object  
   private  
      length, width: integer; 
   public  
      procedure setlength(l: integer);  
      function getlength(): integer;  
      procedure setwidth(w: integer);  
      function getwidth(): integer;  
      procedure draw;
end;

TableTop = object (Rectangle)
   private
     material: string;
   public
      function getmaterial(): string;
      procedure setmaterial( m: string);
      procedure displaydetails;
      procedure draw;
end;

var
   tt1: TableTop;

procedure Rectangle.setlength(l: integer);
begin
   length := l;
end;

procedure Rectangle.setwidth(w: integer);
begin
   width :=w;
end;

function Rectangle.getlength(): integer;  
begin
   getlength := length;
end;

function Rectangle.getwidth():integer;
begin
   getwidth := width;
end;

procedure Rectangle.draw;
var 
   i, j: integer;
begin
   for i:= 1 to length do
   begin
      for j:= 1 to width do
         write(' * ');
      writeln;
  end;
end;

function TableTop.getmaterial(): string;
begin
   getmaterial := material;
end;

procedure TableTop.setmaterial( m: string);
begin
   material := m;
end;

procedure TableTop.displaydetails;
begin
   writeln('Table Top: ', self.getlength(), ' by ' , self.getwidth());
   writeln('Material: ', self.getmaterial());
end;

procedure TableTop.draw();
var
   i, j: integer;
begin
   for i:= 1 to length do
   begin
      for j:= 1 to width do
         write(' * ');
   writeln;
   end;
   writeln('Material: ', material);
end;

begin
   tt1.setlength(3);
   tt1.setwidth(7);
   tt1.setmaterial('Wood');
   tt1.displaydetails();
   writeln;
   writeln('Calling the Draw method');
   tt1.draw();
end.

A continuación se presentan los puntos importantes que deben anotarse:

  • El objeto Tabletop ha heredado todos los miembros del objeto Rectangle.

  • También hay un método de dibujo en TableTop . Cuando el empate método se llama usando un TableTop objeto, el sorteo del TableTop se invoca.

  • Hay una instancia implícita llamada self que se refiere a la instancia actual del objeto.

Cuando se compila y ejecuta el código anterior, produce el siguiente resultado:

Table Top: 3 by 7
Material: Wood

Calling the Draw Method 
* * * * * * *
* * * * * * *
* * * * * * *
Material: Wood