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