A Cecil programozási nyelv

Objektumok, és az öröklődés

Objektumok, és az öröklődés

Az alapvető lehetőségeit a Cecil objektumainak a következő deklarációk jól mutatják. Ezekben a deklarációkban egy egyszerű alakzat (shape) hierarchiát írunk le. (A megjegyzések a Cecilben vagy “--”-vel kezdődnek, és a sor végéig tartanak, vagy “(--” és “--)” jelek közé írandó, és ekkor ezek egymásba ágyazhatók.)

object shape;
object circle isa shape;
object rectangle isa shape;
object rhombus isa shape;
object square isa rectangle, rhombus;

Az objektum deklarációk szintaxisa (kihagyva belőlük a statikus típusellenőrzést, és modularizációt támogató részeket) a következő:

object_decl ::= “object” name {relation} [field_inits] “;”
relation ::= “isa” parents
parents ::= named_object { “,” named_object }
named_object ::= name

A Cecil osztály nélküli (prototípus alapú) objektum modellt használ. Az önálló objektumok implementálják az adatabsztrakciót, és az objektumok közvetlenül egymástól örökölnek. A Cecil ezt a modellt egyrészt az első osztályú osztályok és a meta osztályok problémáját kikerülendő, másrészt az egyszerűsége, valamint az egyedi, nevesített, speciális viselkedéssel ellátott objektumok létrehozhatóságának egyszerűsége miatt használja.

     Öröklődés:

Az objektumok örökölhetnek más objektumoktól. Informálisan ez azt jelenti, hogy a szülő objektumokon értelmezett operációk a gyerek objektumokon is értelmezve lesznek. Az öröklődés lehet többszörös, egyszerűen úgy, hogy több szülő objektumot sorolunk fel a deklarációnál. A rendszer bármiféle többértelműséget tapasztal a mező deklarációkban vagy metódusokban a azt jelezni fogja programozónak. Az egynél többszöri öröklés ugyanattól az objektumtól (akár direkt módon is) nincs más hatással, mint hogy az őst kapcsolatba hozzuk más ősökkel. Nincs olyan ismételt öröklés, mint az Eiffelben. Nem kötelező, hogy egy objektumnak legyen explicit őse. Minden objektum implicit örököl az előre definiált any objektumtól.

Az öröklés a Cecilben megköveteli, hogy a gyerek elfogadja az összes mezőt, és metódust, amit a szülőkben definiáltak. Ezek a mezők, és metódusok felüldefiniálhatók a gyerekben, de olyan lehetőségek, mint kizárni mezőket, vagy metódusokat az öröklésből, vagy átnevezni őket (mint az Eiffelben) nem adottak. A fejlesztők szándékosan választottak egy egyszerűbb öröklődési modellt.

Végül fontos megemlíteni, hogy a kód öröklése különbözik az altípusosságtól.

Példányváltozók létrehozása:

Egy teljesen különböző példányváltozókat létrehozó koncepció bevezetése helyett a tervezők azt a megoldást választották, hogy a példányváltozók egyszerűen örökölnek az objektumtól. Az objektum deklarációk lehetővé teszik statikusan ismert nevű példányok definiálását, míg az objektum konstruktor kifejezések (object constructor expressions) név nélküli objektum példányok létrehozását teszik lehetővé futási időben. Az objektum konstruktor kifejezés szintaktikai és szemantikai értelemben azonos az objektum deklarációval, kivéve azt, hogy az objektumnak nem lesz neve. Változó névvel lehet rá hivatkozni.

Egy példa az objektum konstruktor kifejezésre:

let s1 := object isa square;      -- create a fresh instance of square when executed

A teljes szintaxis:

let_decl ::= [privacy] “let” [ var ] name [type_decl] {pragma} “:=” expr “;”

Az objektumok mezői:

Az objektum állapotok, mint példány változó, osztály változó, a Cecilben mezőkön keresztül, és a hozzájuk tartozó hozzáférési műveletekkel valósítható meg. Például egy nem konstans példány változó (x) deklarálása egy adott (obj) objektumra a következő módon adható meg:

var field x(@obj);

Ez a deklaráció helyet foglal le az obj objektumban egy objektum-referencia számára, valamint létrehozza a hozzá tartozó valódi metódusokat, amiken keresztül a mezőt változtathatjuk (csak ezeken keresztül lehetséges a manipuláció):

method x(v@obj) { prim rtl { } } -- the get accessor method
method set_x(v@obj, value) { prim rtl { := value; } } -- the set accessor method

A hozzáférést biztosító metódusok az obj objektumhoz kapcsoltak, így lehetséges, hogy ha egy x üzenetet küldünk az obj-nak, akkor az meghívja az x-re vonatkozó get hozzáférő műveletet.

A mezőt létrehozó deklaráció szintaxisa:

field_init ::= name [location] “:=” expr
location ::= “@” named_object

Ha nem adjuk meg a var kulcsszót, a mező csak olvasható lesz, ekkor a set művelet nem jön létre. Ekkor a kezdőértéküket vagy az objektum létrejöttekor, vagy egy hozzájuk csatolt inicializáló kifejezéstől kapják.

Ha nem adjuk meg a shared kulcsszót, a mező “copy-down” mező lesz, azaz minden példányváltozóban helyet fog foglalni a saját mező-példány számára. A shared kulcsszó megadásával objektum (≈osztály) szintűvé tehetjük a változót.