A TOM programnyelv egy objektum-orientált programozást támogató programnyelv. Olyannyira OOP nyelv, hogy az objektumok az elemi építőelemei. Az osztályok és a példányok különböznek a nyelvben. Az objektumok egy osztályát az osztályobjektum definíciója és a példány definíciója együtt definiálja. A példány az osztályobjektum allokálható változata.
Vannak allokálható példányok és megvalósítatlan osztályok és példányok. Az allokálható példányokban minden metódusnak implementálva kell lennie, míg a nem allokálható, absztrakt osztályokban és példányokban lehetnek implementálatlan metódusok. Ha egy példány allokálható, annak vagy közvetlenül, vagy indirekten a State osztályból kell öröklődnie, ebben az osztályban vannak definiálva az allokáláshoz szükséges adattagok és metódusok. A State osztály tartalmaz egy isa példányváltozót, mely minden példányra megmutatja, hogy mely osztály objektum írja le a tulajdonságait.
Egy osztály vagy példány definíciója deklarálhat megvalósítatlan metódusokat, ebben az esetben ők maguk is megvalósítatlan osztályok vagy példányok lesznek, nem lehet őket allokálni. Csak olyan példányokat allokálhatunk, melyeknek minden metódusa implementálva van. Létezhetnek olyan példányok is, melyek nem írhatóak le állapottal, csupán metódusok deklarációit és esetleg definíciót tartalmaznak, és persze adattagokat, de csupán azért lettek létrehozva, hogy származtathassunk belőle újabb osztályobjektumokat. Ha nem tartalmaz egyáltalán implementációt egyetlen metódusára sem, akkor olyan példányt kapunk, mint pl. Java programnyelvben az interface.
Minden osztály őse a meta osztály, aminek az őse a meta-meta osztály objektum. Egy osztálynév lehet egy azonosító, vagy egy unit nevével megjelölt azonosító unitnév.azonosító formájú. Egy példány típusának neve maga az osztálynév, az osztályobjektum típusának neve pedig a class (osztálynév).
Például
a my_foo
egy Foo
példány
típusa, vagy valamely alosztályának típusa,
ha:
és a foo_class
a Foo
osztályobjektumának típusa, vagy annak valamely
alosztálya, ha:
Ha már létező osztályhoz hasonló osztályt szeretnénk létrehozni, mely rendelkezik egy másik osztály tulajdonságaival, akkor nagy segítség számunkra a TOM programozási nyelv által kínált öröklődés. Sajnos a TOM csak public öröklődést támogat, azaz minden az ősosztályban definiált metódus elérhető az alosztályokban is, ellentétben a C++ által nyújtott privat öröklődéssel. A gyermekosztály örökli a szülő, azaz a superosztály minden tulajdonságát, így adattagjait és metódusait is. A többszörös öröklődés megengedett a nyelvben, azaz egy gyermekosztály, másnéven a leszármazott osztály több superosztály tulajdonságait is örökli, de azok superosztályainak tulajdonságait csak egyszeresen. Azonban probléma adódik, ha több superosztályában is megtalálható egy metódus neve, vagy egy adattag, ami esetleg nem azok közös superosztályaiban van megvalósítva. Ekkor a leszármazott osztályban ezen metódusokat vagy adattagokat újra kell definiálni, vagy megmondani, hogy mely szülőtől örökölje azokat. Az utóbbi megoldásra egyelőre nincs lehetőség a nyelvben, tehát újra kell definiálni. Az öröklődés szintaxisa a nyelvben:
Az interface rész a deklarációkat tartalmazza, azt, ami látható az osztályból, az implementation rész pedig a megvalósításokat is. Az implementation részt a programozó írja, az interface részt pedig általában az interface generátor hozza létre automatikusan. A fordítás során a compiler csak az implementation részeket olvassa, és az esetleges függőségek kapcsán keresi az interface részekben, hogy mely deklarációk hol vannak implementálva. Az interface részben leírt metódusdeklarációk, változók, és az implementation részben leírtak között nem lehet különbség, ugyanabban a formában kell megjelenniük, különben a fordító hibát jelez. Az object variables rész az objektumváltozókat tartalmazza, tehát az objektumváltozók felsorolása. Egy objektumváltozó deklarálása a következőképpen néz ki:
A static szót
csak
osztályobjektum definiálásakor
használhatjuk, példány esetén nem. Ha a
változó
elé odaírjuk a static szót, akkor abból a
változóból egy közös
változó lesz az
összes ebbe az osztályba tartozó
példány esetén,
megváltoztatásával minden
példányban megváltozik ez az érték.
Tehát ez egy osztályobjektumra vonatkozó
változó lesz, éppúgy, mint C++ -ban.
A local szót csak static típusu változó esetén használhatjuk. Jelentése több szálon futó alkalmazások esetén van, azt jelenti, hogy minden egyes futó szálnak legyen egy saját ilyen változója.
A redeclare szót akkor kell használnunk, ha egy superosztályból örökölt változót akarunk újradeklarálni a leszármazott osztályunkban. Használhatjuk akkor, ha egy ősosztálybeli változó típusát szeretnénk megváltoztatni, de csak az eredeti, az ősosztályban megadott típus egy altípusa lehet az új típus. Például char típusról long típusra nem lehet újradeklarálni.
A metódusoknak a deklarációit csak az interface részben lehet elhelyezni, az implementációit pedig csak az implementation részben. Ezekről még az Alprogramok részben bővebben lesz szó.
A TOM programnyelv definiál
néhány elemi osztályt, melyek a compilerbe
beépített unitban vannak definiálva,
ennek a unitnak a neve: _builtin_
. Megj.: Erre a unitra
lehetetlen
hivatkozni, mert a TOM nem engedi az azonosítókat
aláhúzással kezdeni. Ezek az
osztályok pedig a következők:
_builtin_.Top: Ez az implicit ősosztálya minden definiált osztálynak. Tartalmazza a builtin, a statikus kötés, és az operátorok definicióját.
_builtin_.Any: Ez az implicit alosztálya minden definiált osztálynak. Ha egy metódus bármivel visszatérhet, akkor a visszatérési típust Any-nek kell definiálni.
tom.State:
Az
ősosztálya minden
allokálható példánnyal rendelkező
osztálynak. Ez az osztály teszi lehetővé
többek között a dinamikus kötést.
Egy örökölt osztály
esetén a gyermek
osztály felül tudja írni az
ősosztályától örökölt
metódusokat. Legyen pl. egy Counter
osztályunk, ami a State
osztályból
származik, és ebból származtassuk a TwoCounter
osztályt, aminek az a
feladata, hogy a nextValue
metódus meghívásakor 2-vel növeli az
értékét, szemben a Counter
osztály nextValue
metódusával.
Ha a nextValue
–t
meghívjuk a TwoCounter
–től,
az 2-vel növeli az értéket, egyébként
teljesen ugyanúgy viselkedik, mint a Counter
-ben.
Egy alosztály rendelkezik ugyanazokkal a
metódusokkal,
mint amelyekkel
szülőosztálya rendelkezett, és ezek
meghívásakor ugyanazt csinálja is, feltéve,
hogy nem írta felül azokat. Például a
következő metódus lekérdezi a nextValue
–t
a Counter
objektumtól, mint argumentumot.
Amikor ez a metódus egy TwoCounter
objektummal találkozik a várt Counter
objektum helyett, a nextValue
metódus még mindig érvényes.
Tulajdonképpen bármilyen, a Counter
által
értelmezett metódus érvényes a TwoCounter
objektumon is, mivel az alosztálya.
De mi történik a következő kódban?
A c2
változónak Counter
–beli
típusa van, de jelenleg egy TwoCounter
objektumra mutat. Ilyenkor a nextValue
metódus meghívásakor az aktuálisan
hívott
osztály szerinti metódus hívódik.
Egy példány közvetlenül elérheti a saját példányváltozóit, és az osztályának összes elérhető osztályváltozóját. Egy osztály objektum közvetlenül elérheti a saját osztályváltozóit, amit deklarál, vagy örökölt valamely superosztályától. Más közvetlen változóelérés nem lehetséges, a többi változót metódusokon keresztül lehet csak elérni.
Fordítási időben nagyon fontos az adattagok és a metódusok védelmének szigorú fogalma, azaz a láthatóság megadhatósága. Minden metódus és változó számára a TOM három különböző láthatósági szintet definiál:
private: Az adott elem csak az aktuális osztályból érhető el.
protected: Az adott elem csak az aktuális osztályból, és annak leszármazottjaiból érhető el, ez az alapértelmezett láthatóság a példány- és osztályváltozók számára.
public: Az adott elem minden osztály számára elérhető. Ez az alapértelmezett láthatóság minden metódus számára.
Egy publicnak definiált változó azonban nem közvetlenül érhető el az adott osztályon kívülről (lásd feljebb), egy hozzáférő és egy módosító metódust kell hozzá definiálni. Ha a változót mutable-nek deklaráljuk, akkor ha a változót publicnak deklaráljuk, akkor egy módosító metódus definiálódik hozzá.
/* Hozzáférő */
/* Módosító */