Pascal - zorientowany obiektowo

Możemy wyobrazić sobie nasz wszechświat złożony z różnych obiektów, takich jak słońce, ziemia, księżyc itp. Podobnie, możemy wyobrazić sobie nasz samochód złożony z różnych obiektów, takich jak koło, kierownica, przekładnia itp. Tak samo, istnieją koncepcje programowania obiektowego, które zakładaj wszystko jako obiekt i wdrażaj oprogramowanie przy użyciu różnych obiektów. W Pascalu istnieją dwa strukturalne typy danych używane do implementacji obiektu świata rzeczywistego -

  • Typy obiektów
  • Typy klas

Koncepcje zorientowane obiektowo

Zanim przejdziemy do szczegółów, zdefiniujmy ważne terminy Pascal związane z Pascalem zorientowanym obiektowo.

  • Object- Obiekt to specjalny rodzaj rekordu, który zawiera pola, takie jak rekord; jednak w przeciwieństwie do rekordów obiekty zawierają procedury i funkcje jako część obiektu. Te procedury i funkcje są przechowywane jako wskaźniki do metod skojarzonych z typem obiektu.

  • Class- Klasa jest definiowana prawie tak samo jak obiekt, ale istnieje różnica w sposobie ich tworzenia. Klasa jest umieszczana na stercie programu, a obiekt na stosie. Jest to wskaźnik do obiektu, a nie sam obiekt.

  • Instantiation of a class- Tworzenie instancji oznacza tworzenie zmiennej tego typu klasy. Ponieważ klasa jest tylko wskaźnikiem, kiedy deklarowana jest zmienna typu klasy, pamięć jest przydzielana tylko dla wskaźnika, a nie dla całego obiektu. Tylko wtedy, gdy jest tworzony przy użyciu jednego z jego konstruktorów, przydzielana jest pamięć dla obiektu. Instancje klasy są również nazywane „obiektami”, ale nie myl ich z obiektami Object Pascal. W tym samouczku napiszemy „Object” dla Pascal Objects i „object” dla obiektu koncepcyjnego lub instancji klasy.

  • Member Variables - Są to zmienne zdefiniowane wewnątrz klasy lub obiektu.

  • Member Functions - Są to funkcje lub procedury zdefiniowane w klasie lub obiekcie i służą do uzyskiwania dostępu do danych obiektu.

  • Visibility of Members- Składowe obiektu lub klasy są również nazywane polami. Te pola mają różną widoczność. Widoczność odnosi się do dostępności członków, tj. Dokładnie tam, gdzie ci członkowie będą dostępni. Obiekty mają trzy poziomy widoczności: publiczny, prywatny i chroniony. Klasy mają pięć typów widoczności: publiczne, prywatne, ściśle prywatne, chronione i publikowane. Szczegółowo omówimy widoczność.

  • Inheritance- Gdy Klasa jest zdefiniowana przez dziedziczenie istniejących funkcji Klasy nadrzędnej, mówi się, że jest dziedziczona. Tutaj klasa potomna odziedziczy wszystkie lub kilka funkcji składowych i zmiennych klasy nadrzędnej. Obiekty mogą być również dziedziczone.

  • Parent Class- Klasa, która jest dziedziczona przez inną klasę. Nazywa się to również klasą podstawową lub superklasą.

  • Child Class- Klasa, która dziedziczy po innej klasie. Nazywa się to również podklasą lub klasą pochodną.

  • Polymorphism- Jest to koncepcja zorientowana obiektowo, w której ta sama funkcja może być używana do różnych celów. Na przykład nazwa funkcji pozostanie taka sama, ale może mieć różną liczbę argumentów i może wykonywać różne zadania. Klasy Pascala implementują polimorfizm. Obiekty nie implementują polimorfizmu.

  • Overloading- Jest to rodzaj polimorfizmu, w którym niektóre lub wszystkie operatory mają różne implementacje w zależności od typów ich argumentów. Podobnie funkcje mogą być przeciążane przy różnych implementacjach. Klasy Pascal implementują przeciążenie, ale Objects nie.

  • Data Abstraction - Dowolna reprezentacja danych, w której szczegóły implementacji są ukryte (abstrakcyjne).

  • Encapsulation - Odnosi się do koncepcji, w której wszystkie dane i funkcje składowe hermetyzujemy razem, aby utworzyć obiekt.

  • Constructor - Odnosi się do specjalnego typu funkcji, która będzie wywoływana automatycznie, gdy pojawi się formacja obiektu z klasy lub obiektu.

  • Destructor - Odnosi się do specjalnego typu funkcji, która będzie wywoływana automatycznie, gdy obiekt lub klasa zostanie usunięty lub wyjdzie poza zakres.

Definiowanie obiektów Pascal

Obiekt jest deklarowany przy użyciu deklaracji typu. Ogólna forma deklaracji obiektu jest następująca -

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

Zdefiniujmy obiekt Rectangle, który ma dwóch członków danych typu całkowitego - length i width i niektóre funkcje składowe do manipulowania tymi składowymi danych i procedurę rysowania prostokąta.

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;

Po utworzeniu obiektów będziesz mógł wywoływać funkcje składowe związane z tym obiektem. Jedna funkcja członkowska będzie mogła przetwarzać zmienną składową tylko powiązanego obiektu.

Poniższy przykład pokazuje, jak ustawić długości i szerokości dla dwóch obiektów prostokątnych i narysować je, wywołując funkcje składowe.

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);

Poniżej znajduje się kompletny przykład pokazujący, jak używać obiektów w Pascalu -

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.

Kiedy powyższy kod jest kompilowany i wykonywany, daje następujący wynik -

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

Widoczność elementów składowych obiektu

Widoczność wskazuje dostępność elementów składowych obiektu. Elementy składowe obiektu Pascal mają trzy typy widoczności -

Sr.No Widoczność i dostępność
1

Public

Członkowie mogą być wykorzystywani przez inne jednostki poza jednostką programu

2

Private

Członkowie są dostępni tylko w bieżącej jednostce.

3

Protected

Składowe są dostępne tylko dla obiektów pochodzących z obiektu nadrzędnego.

Domyślnie pola i metody obiektu są publiczne i są eksportowane poza bieżącą jednostkę.

Konstruktorzy i niszczyciele obiektów Pascal -

Constructorsto specjalne typy metod, które są wywoływane automatycznie za każdym razem, gdy tworzony jest obiekt. Tworzysz konstruktor w Pascalu, po prostu deklarując metodę z konstruktorem słowa kluczowego. Zwykle nazwa metody to Init, jednak można podać dowolny poprawny własny identyfikator. Do funkcji konstruktora można przekazać dowolną liczbę argumentów.

Destructorsto metody wywoływane podczas niszczenia obiektu. Metody destruktora niszczą alokację pamięci utworzoną przez konstruktory.

Poniższy przykład dostarczy konstruktora i destruktora dla klasy Rectangle, który zainicjuje długość i szerokość prostokąta w momencie tworzenia obiektu i zniszczy go, gdy wyjdzie poza zakres.

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.

Kiedy powyższy kod jest kompilowany i wykonywany, daje następujący wynik -

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

Dziedziczenie dla obiektów Pascal

Obiekty Pascal mogą opcjonalnie dziedziczyć po obiekcie nadrzędnym. Poniższy program ilustruje dziedziczenie w obiektach Pascal. Stwórzmy kolejny obiekt o nazwieTableTop, który dziedziczy po obiekcie 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.

Poniżej przedstawiono ważne punkty, które należy zanotować -

  • Obiekt Tabletop odziedziczył wszystkie elementy członkowskie obiektu Rectangle.

  • W TableTop jest również metoda losowania . Gdy remis metoda jest wywoływana za pomocą blatem obiekt, rysować blatem dostaje wywoływany.

  • Istnieje niejawna instancja o nazwie self która odnosi się do bieżącego wystąpienia obiektu.

Kiedy powyższy kod jest kompilowany i wykonywany, daje następujący wynik -

Table Top: 3 by 7
Material: Wood

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