CA - Visual Objects

Objektum-orientált programozás

Osztályok

Osztályokat a class utasítással definiálhatunk. CA-VO -ban is három láthatósági szint van az egyes tagokra:

Van még egy negyedik is, az instance, ami önmagában ugyanaz mint a protect, viszont az elérése lassabb. Még egy különbség, hogy más módon viselkedik az úgynevezett access és assign metódusokkal. Az ilyen instance -oknak is külön lehet láthatósága a fentiek közül (pl. hidden instance).

Az osztályok metódusait nem az osztály törzsében deklaráljuk/definiáljuk, hanem külön, a metódus után írva az osztály nevét. Ha viszont erősen típusos a metódusunk, akkor az osztályban is deklarálni kell (csak a nevét). Metódusok láthatóságát nem lehet megadni. A konstruktornak nagyjából megfelel az Init metódus, a destruktornak pedig az Axit() (Exit???). Mivel van automatikus szemétgyűjtés ezért nem kötelező ezeket megadni.

Ha egy osztály statikus, akkor csak az adott modulban látszik. Természetesen metódusokra is működik az export local.

class Apple hidden Meret as int export Szin as int declare method Init method Init(m as int, sz as int) class Apple Meret := m Szin := sz return self

Az access és az assign metódusok nagyon hasonlítanak a C#-os propertykre (get/set). Előbbivel egy nem exportált member értékét lehet elkérni, az utóbbival pedig értékadás operátor segítségével megváltoztatni. assign metódusoknál érdemes visszaadni a változó értékét, hogy lehessen értékadás láncokat csinálni. Mostantól a/a metódusoknak fogom hívni ezeket, mert egyszerűbb leírni.

class Apple hidden instance meret as int access meret class Apple return meret assign meret(m) class Apple meret := m return meret function Start() local a as Apple a := Apple{} a:meret := 15 // ez az assign ? a:meret // ez meg az access _Accept("") return nil

Az instance változók pont az ilyen esetekre lettek kitalálva. Amikor egy ilyen a/a metódust ugyanazzal a névvel definiálunk mint az instance változót, akkor onnantól kezdve minden hivatkozás arra a névre (akár külső akár belső) a metódust fogja meghívni, persze kivéve az a/a metóduson belül mert az úgy fura lenne.
Amennyiben az a/a metódust nem instance változóval használjuk, akkor az osztályon belüli hivatkozások nem a metódust fogják hivni, hanem közvetlenül a változót.

Egy érdekes fogalom a virtuális változó, ami olyan változót akar jelenteni, ami nincsen explicit módon definiálva az osztályban, hanem ilyen a/a metódusokkal pakolgatjuk össze. Ha az osztályon belülről akarunk hivatkozni egy ilyen változóra, akkor a self: prefixet elé kell írni (hasonlóan akkor is, ha egy nem instance -os a/a metódust akarunk meghívni).

class Apple hidden meret as int access nincsisilyen class Apple return meret + 3 assign nincsisilyen(m) class Apple meret := m - 3 return meret

Azt mondjuk, hogy egy változó korán köt, hogy ha a változó helye a memóriában fordítási időben már ismert, így a fordító tud kódot generálni hozzá. Ennek az ellentéte a későn kötés, amikor nem tudjuk a helyet, ilyenkor futási időben keresi ki egy táblából. Előbbieket érdemesebb használni, gyorsabb lesz tőle az alkalmazás.

láthatóság kötés
export korán, ha lehet
instance mindig későn
hidden mindig korán
protect mindig korán

Így már érthető, hogy az instance miért lasabb mint a protect.

Objektumok

Struktúráknál volt olyan, hogy is. Na az itt nem megengedett, az objektumokat a szemétgyűjtő kezeli. Az objektumot úgy hozzuk létre, mintha egy metódust hívnánk, de () helyett {} -ek közé kell tenni az argumentumokat. Ha van az osztálynak Init metódusa, akkor az fog meghívódni, ha nincs akkor a default. Az objektum tagjaira a : operátorral hivatkozhatunk.

function Start(p) local a as Apple a := Apple{10, 2} ? a:Szin _Accept("") return nil

Minden objektum a beépített object típusból származik.

Öröklődés

Származtatni az inherit kulcsszóval lehet. A származtatott osztály örökli az ősosztály minden tagját és minden metódusát, viszont az ősosztály hidden dolgai nem lesznek láthatóak a származtatottban.

class Gyumolcs protect Meret as int export Szin as int class Apple inherit Gyumolcs declare method Init

Többszörös öröklődés nincs.

Polimorfizmus, dinamikus kötés

Metódusokat szerencsére felül lehet definiálni. Mivel az objektum változó nagyon olyan mint egy pointer, ezért mindig a származtatott osztály metódusa fog meghívódni.

class Base class Derived inherit Base method foo class Base ? "base::foo" method foo class Derived ? "Derived::foo" function Start() local p as Base p := Derived{} p:foo() _Accept("") return nil

Interfészek

Úgy tűnik nincs...