Az Oz/Mozart programozási nyelv

Objektum-orientált programozás

Objektum-orientált programozás

Osztályok

Az Oz az objektum orientált programozást is támogatja, léteznek a megfelelő szintaktikai elemek, és az implementációja is megközelítőleg annyira hatékony, mint a függvényhívásoké.
Az osztályok olyan chunk-ok, amelyek tartalmaznak:

A következő példa egy számláló osztály.
declare Counter local Attrs = [val] MethodTable = m(browse:MyBrowse init:Init inc:Inc) proc {Init M S Self} init(Value) = M in (S.val) := Value end proc {Inc M S Self} X inc(Value)=M in X = @(S.val) (S.val) := X+Value end proc {MyBrowse M=browse S Self} {Browse @(S.val)} end in Counter = {NewChunk c(methods:MethodTable attrs:Attrs)} end
Más megközelítésből class-ként is létrehozhatjuk a következő képpen:
class Counter attr val meth browse {Browse @val} end meth inc(Value) val := @val + Value end meth init(Value) val := Value end end
Az osztályok statikus metódusait vesszővel lehet kijelölni.
A metódusokból @A szimbólummal hivatkozhatunk az A nevű attribútumra, értéket pedig az A := E utasítással adhatunk neki. Az attribútumok tartalmazzák az osztály állapotát, értéket adhatunk neki, akkor is, ha már van értéke (destruktív értékadás, ez csak attribútumok esetén megengedett), és csak az objektumon belülről látszik.
A metódusok osztályokhoz rendelt eljárások.
Az osztályok metódusai egymást is hívhatják, ha van egy C nevű osztály m(…) metódus fejjel, a metódusokban szereplő C, m(…) ugyanazon az objektumon meghívja az m(…) metódust. Az OZ ezt hívja statikus metódushívásnak, ilyen csak metódus törzsében szerepelhet.
Névtelen osztályok az X = class $ ... end formában definiálhatók.
A New/3 generic eljárással hozhatunk létre egy objektumot az osztályból, ennek első paramétere az osztály, a második pedig az inicializáló metódus. Egy objektum metódusát { objNev metodNev(parameter_1 … ) } formában hívhatjuk meg.
Az objektumok „feature” –öket is tartalmazhatnak, ezek a rekordokhoz hasonló, állapotmentes komponensek, a következő formában deklaráljuk őket:
class X … feat A1[:initVal_1] … AN[:initVal_n] …. end
Mint a rekordoknál, itt a feature –öknek is van egy hivatkozott mezőjük, amit bármilyen OZ értékkel le lehet kötni. Egy objektum feature –ére az infix „.” operátorral hivatkozhatunk. Objektum létrehozásakor a feature –ök inicializálása initVal_i –re történik, ezt azonban nem kötelező megadni.

Objektumok

Objektumokat kérhetünk az osztálytól. Az Oz belső szerkezetében valójában az objektum Object típusú, de van egy mutatója az ő őseinek számító classokra. Példa:

declare C {NewObject Counter init(0) C}

Öröklődés

Létezik, a szülőket fel kell sorolni a deklarációnál a from kulcsszó segítségével:

class A from B ... end
Két feltétele van az öröklésnek.
Az egyik, hogy a származtatás aciklikus, tehát az öröklődési gráf mindenképpen háló lesz. A másik, hogy ne örököljön azonos nevű tagot az osztály több ősétől.
A következő példát az Oz nem engedi lefordítani a többszörös öröklődés ütközése miatt.
class A meth m(...) ... end end class B meth m(...) ... end end class C from A B end
Illegális származtatás esetén a fordító nem jelez hibát és a program megfelelően működik, mindaddig, míg nem próbáljuk meg a problémát okozó metódust elérni. Ekkor futási idejű hibát kapunk.
A láthatóság szabályozására nincs külön nyelvi elem, de elérhető, hogy egy metódus csak az osztályon belül látszódjon. A nyelv megkülönbözteti a public, protected és private metódusokat, de nem ad erre direkt jelölést.
A „normális” ún. literállal címkézett metódus publikus (public):
class C from … meth a(…) … end … end
Metódusokat azonban nem csak literálokkal, hanem változónévvel is címkézhetjünk, az ilyen metódusok lesznek privátok (private) az osztályra nézve:
class C from … meth A(…) … end … end
Védett (protected) metódust pedig úgy definiálhatunk, hogy először megadunk egy private metódust, majd azt eltároljuk egy attribútumban:
class C from … attr pa:A meth A(X) … end meth a(…) {self A(5)} … end … end
Ezután a C osztály leszármazottaiban az állabi módon elérhető lesz az A védett metódus:
class C1 from C meth b(…) L=@pa in {self L(5)}… end … end

Polimorfizmus, dinamikus kötés

Az objektumok metódusait a rendszer mindig dinamikusan köti.

Interfészek

Nincsenek interfészek.