A Pascal nyelv

Objektumok a Pascal nyelveben

Objektumok a Pascal nyelvben

Objektumorientált programozásra Turbo Pascalban az 5.5-ös verziótól kezdve van lehetőségünk. Ez a megvalósítás támogatja a legfontosabb OOP jellemzőket, az egységbe zárást (encapsulation), az öröklődést (inheritance) és a többrétűséget (polymorphism).

Osztályt a következőképpen definiálhatunk:

Ahol az ősosztályt nem kötelező megadni. A többszörös öröklődés nem támogatott. Az elsőnek megadott mezők és metódusok teljes láthatósággal rendelkeznek (public), míg a private kulcsszó utániak csak abban a unitban láthatóak, ahol az osztályt deklaráltuk. Private szekciót Turbo Pascalban csak a 6.0-ás verziótól használhatunk.

Metódusaink lehetnek virtuálisak, ezt a virtual kulcsszóval jelezhetjük, de nem lehetnek absztraktak. Az osztálydefiníció után a programszövegben szerepelnie kell az összes metódus törzsének (ami persze lehet üres).

Példa:

type pont = object x,y : integer; procedure rajzol; virtual; procedure sokatrajzol (sok : integer); end; kor = object (pont) r : integer; procedure rajzol; virtual; end; procedure pont.sokatrajzol (sok : integer); var a : integer; begin for a:=1 to sok do begin rajzol; inc(x); end; end; procedure pont.rajzol; begin putpixel(x,y); end; procedure kor.rajzol; begin circle(x,y,r); end;

A fenti példában rajzol virtuális. A pont és kor osztályok rendelkeznek a sokatrajzol metódussal, de az mindig az az őt hívó objektum osztályának megfelelő rajzol metódust fogja meghívni (a késői kötés /late binding/ Virtuális Metódus Tábla /Virtual Method Table/ segítségével valósul meg).

Megjegyzendő még, hogy virtuális metódust csak virtuális metódussal, nem virtuális metódust pedig csak nem virtuálissal lehet a származtatás folyamán "felülírni". Mezők felüldefiniálása nem lehetséges, tehát a fenti példában kor-nek nem lehet x,y nevű mezője, valamint egyik rajzol metódusnak sem lehetne x,y nevű paramétere vagy lokális változója (fordítási hibát eredményezne).

Lehetőségünk van még konstruktor és destruktor metódusok írására is, de ehhez fontos tudnunk, hogy ezek hívása nem történik meg automatikusan.

Példa:

type mokus = object constructor Init (mogyoroszam:integer); destructor Done; end; constructor Init (mogyoroszam:integer); begin { valami… } end; destructor Done; begin { valami… } end; var misimokus : mokus; mutatomokus : ^mokus; begin {1} misimokus.Init(3); misimokus.Done; {2} new(mutatomokus); mutatomokus^.Init(2); mutatomokus^.Done; dispose(mutatomokus); {3} new(mutatomokus,Init(1)); dispose(mutatomokus,Done); end.

Misimokus számára a program indulásakor lefoglalódik a szükséges memóriaterület a stack-ből, mivel ő nem dinamikus objektum. Sajnos az Init és Done metódusok meghívásáról nekünk kell gondoskodnunk.

Mutatomokus helyzete szerencsésebb, mivel ő dinamikus objektum, valójában csak egy pointer, mely kezdetben nem mutat semmire (nem determinisztikus). Ahhoz, hogy használhassuk először memóriát kell igényelnünk a heap-ből, majd a program végén ezt a memóriát felszabadítanunk {2}. (Bár a felszabadítás megtörténik kilépéskor.) Ezt a négy lépést összevonhatjuk két lépésbe, a memóriafoglalással együtt meghívhatunk egy konstruktor, a felszabadítással együtt pedig egy destruktor metódust {3}.