A nyelv objektum orientált kiterjesztése, az Object Oriented
Modula-2 (OOM-2) ad eszközöket az objektum elvû programfejlesztéshez.
Az osztályok deklarációjában felsorolhatók
az új (konstans) attribútumok, az új és újradefiniált
metódusok, az ôsosztály azonosítója és
lehet itt egy inicializációs rész is. A publikus komponenseket
a REVEAL kulcsszó után kell felsorolni.
Példányok létrehozása a CREATE
eljárással történik, ennek hatására
a példányok számára szükséges dinamikus
memória lefoglalásra kerül, valamint az osztályok
inicializációs része fut le. Ez az inicializációs
rész a konstruktor szerepét tölti be és ez szintaktikailag
a metódusokon kívül, azok után írt BEGIN...END
blokkban elhelyezkedõ utasítássorozat. A DESTROY
pedig megsemmisíti az objektumot.
Ekkor, ha van a BEGIN..END blokkban FINALLY
rész, akkor az lefut (destruktornak megfelelõ viselkedés).
Az osztályok READONLY-val jelölt attribútumai
csak olvashatóak. Például:
MODULE Example;
CLASS Ellipse;
REVEAL SetCenter, SetAxes, Area, dimenzio; (* ezek láthatóak
*)
VAR major, minor: REAL; (* mind a 4 komponens rejtett
*)
VAR x, y: REAL;
CONST dimenzio = 2; (* az alakzatunk két dimenziós *)
PROCEDURE SetCenter (xcoord, ycoord: REAL);
BEGIN
x:=xcoord;
y:=ycoord;
END SetCenter;
PROCEDURE Area() : REAL;
BEGIN
.....
END Area;
.....
BEGIN (* Inicializációs rész *)
SetCenter(0.0);
radius:=0.0;
END Ellipse;
VAR ell: Ellipse;
BEGIN (* A fõprogram itt kezdõdik *)
CREATE( ell );
ell.SetCenter(1.2, 5.6);
....
END Example.
Objektumokat egymásnak értékül adhatunk
és vizsgálhatjuk az egyenlõségüket. Ezek
a mûveletek egyszerûen a referenciák közötti
mûveleteknek felelnek meg.Az EMPTY referencia
érték jelenti a nem inicializált objektumot, hasonló
a szerepe, mint a NIL pointernek a mutatók
között.
Az ADT-k megvalósítására
használt technika osztályoknál is mûködik:
az osztály leírása két külön részre
bomlik, amelyet külön-külön file-ban kell tárolni.
A definíciós modulban nem írunk metódusoknak
törzset és csak a publikus metódusok deklarációit
szerepeltetjük itt, az attribútumokkal hasonló a helyzet.
Az implementációs modul csak a törzset tartalmazza:
a privát attribútumokat és a publikus és privát
metódusok implementációját, a publikus attributumokat
tehát nem kell itt is leírni. Például:
DEFINITION MODULE Shapes;
CLASS Ellipse;
REVEAL SetCenter, SetAxes, Area, dimension;
(* ezek láthatóak *)
VAR major, minor: REAL; (* mind a 4 komponens rejtett
*)
VAR x, y: REAL;
CONST dimension = 2; (* az alakzatunk két dimenzios *)
PROCEDURE SetCenter (xcoord, ycoord: REAL);
PROCEDURE Area() : REAL;
(* Sikerült-e beállítani
a tengelyek hosszát *)
PROCEDURE SetAxes(a, b: REAL) : BOOLEAN;
.....
END Ellipse;
END Shapes.
Az implementációs modulba kerûlnek a metódusok tôrzsei:
IMPLEMENTATION MODULE Shapes;
CLASS Ellipse;
PROCEDURE SetCenter (xcoord, ycoord: REAL);
BEGIN
x:=xcoord;
y:=ycoord;
END SetCenter;
PROCEDURE Area() : REAL;
BEGIN
.....
END Area;
......
END Ellipse;
END Shapes.
Az öröklõdéshez használt kulcsszó
az INHERIT, mely után a szülõ osztály
azonosítója következik.A szabvány OOM-2 esetében
a többszörös
öröklõdéssel járó kellemtlenségek
fel sem merülnek: az csak az egyszeres öröklôdést
támogatja. A leszármazott osztály a szülõ
minden atrribútumához és metódusához
hozzáfér, de az implementációs részben
bevezetett (rejtett) komponensekhez nem fér hozzá.
A gyerek osztály a szülõ attribútumait
nem definiálhatja át, a metódusokat viszont igen,
ilyenkor egy az eredeti metódussal megegyezõ interfészû
eljárás jöhet szóba. Az átdefiniálsokat
az OVERRIDE kulcsszó vezeti be. Szülõ
metódusára minõsített nevekkel hivatkozhatunk,
ez nem csak a közvetlen szülõre, hanem az öröklõdési
lánc minden osztályára igaz. A következõ
példában az ellipszisbõl származtatjuk a kört:
DEFINITION MODULE Shapes2;
FROM Shapes IMPORT Ellipse;
CLASS Circle;
INHERIT Ellipse;
OVERRIDE PROCEDURE Area() : REAL;
OVERRIDE PROCEDURE SetAxes(a, b: REAL) : BOOLEAN;
END Circle;
END Shapes2;
Az implementációs modulban nem kell mégegyszer
kijelôlni a szülôosztályt. Csak az új metódus
tôrzsét kell megadnunk. :)
A mi példánkban kör esetén nincs szükség
külön nagytengely hosszra (major) és kistengely hosszra
(minor). A terület kiszámittásához most elég
csak mondjuk a minor-t használni.
IMPLEMENTATION MODULE Shapes2;
FROM RealMath IMPORT pi;
CLASS Circle;
OVERRIDE PROCEDURE Area() : REAL;
BEGIN
RETURN minor*minor*pi;
END Area;
OVERRIDE PROCEDURE SetAxes(a, b: REAL) : BOOLEAN;
BEGIN
IF a<>b THEN
RETURN FALSE;
ELSE
minor:=a;
major:=b;
RETURN TRUE;
END;
END SetAxes;
END Circle;
END Shapes2.
Az ABSTRACT kulcsszóval jelölt metódusok
az absztrakt metódusok. Egy osztály absztrakt, ha van legaláb
egy absztrakt metódusa. Ha az osztaly absztrakt, akkor a CLASS
kulcsszó
elé is ki kell tenni az ABSTRACT kulcsszót.
Az implementációs részben tilos absztrakt metódusnak
törzset írni. Ha csak absztrakt metódusunk van, akkor
elég ott csak az osztály üres deklarációját
szerepeltetni.
Érdekesség, hogy a nyelv nem kulcsszavakkal támogatja az adatelrejtést, ehelyett szétválasztja az osztály import-export felületét a törzstôl. Amit a definíciós modulban deklarálunk, látható lesz kívülrôl; ez megfelel a public direktívának. Amit csak az implementációs modulban deklarálunk, azt kívülrôl nem látható; ez megfelel a private direktívának.