A Dylan programozási nyelv

Objektum orientált programozás



Objektum orientált programozás

A Dylan egy objektum orientált nyelv. A nyelv típusrendszere minden egyes objektumot kategorizál. A típus meghatározza egy objektum videlkedését. Generikus függvény hívása esetén a függvény megvizsgálja a paraméterként kapott objektum típusát és ez alapján dönti el, hogy melyik metódusnak kell lefutnia.

A nyelvben négy különböző típusfajta létezik:

A Dylan nyelvben a típusoknak is van típusa. Minden típus a type osztály egy példánya. Az osztályok a class osztály példányai (maga a class osztály is a class példánya). A type egy absztrakt osztály, az ő leszármazottjai az osztályok és az összes egyéb típus (a singletonok, az unió típus és a limited típus).

A típus protokoll

A nyelv típus protokollja a következőket foglalja magába:
* Az összes típus használható metódus paraméterének specializálására, konstansok és változók (bindings) és osztályok adattagjainak (slots) specializálására.
* Az instance?(object, type) megadja, hogy az objektum példánya-e a típusnak.
* A subtype?(type1, type2) segítségével tesztelhető, hogy egyik típus altípusa-e egy másik típusnak.
* A make(type, ...) példányok létrehozására való. Pédányt létrehozni csak akkor lehet, ha a típus példányosítható.
Részlet a Dylan osztályhierarchiájából
Az osztályhierarchia csúcsán az object áll.
Az object-nek minden objektum példánya és minden típus az altípusa.
Minden osztály követett vagy közvetlen módon az object-ből származik.
Az ábrán látható, hogy az egyszerű objektumok osztályai (character, boolean, integer) hogyan származtathatók az object-ből.
Maguk az osztályok a class osztály példányai.
Ha például létrehozunk egy integer típusú 'i'objektumot, akkor azt mondhatjuk, hogy az 'i' az integer egy példánya.
Maga az integer osztály (akár az összes többi osztály) viszont a class egy példánya.
Az integer osztály (közvetett módon) példánya a type osztálynak és az object osztálynak is.
Fontos, hogy a class osztálynak minden osztály a példánya (még maga a class is), nem pedig a leszármazottja.
Azért hasznos, hogy az osztályok is rendelkeznek típussal, mert így az osztályokon is végrehajthatunk műveleteket (a class osztályban definiált műveleteket).
Például az unió típus létrehozása a type osztályban definiált union művelettel történhet.
Korlátozott típust a class osztályban definiált limited művelettel hozhatunk létre.
Fontos megjegyezni, hogy az osztályhierarchiának ezt a részét a programozó nem módosíthatja. Nem lehet létrehozni olyan osztályt ami a type leszármazottja.

Osztályok

Osztályok létrehozásának két módja van: az egyik hogy make utasítást alkalmazunk a class típuson (azaz létrehozzuk a egy példányát, amely minden osztály ősosztálya).
A másik (sokkal elterjedtebb) módszer a define class használata.
Példaként nézzük meg a lehető legegyszerűbb osztálydefiníciót:

define class () end class ;
Ezzel létrehoztunk egy new nevű osztályt, amely örököl az object típustól, és nem definiáltunk új adattagokat.
A következő példában többszörös öröklődést alkalmazunk, és most sem definiálunk semmi újdonságot:

define class (, ) end class ;

Amikor egy típust definiálunk akkor megadjuk a közvetlen ősosztályait. De a típusnak közvetett ősosztályai is vannak, pl. minden típusnak közvetett módon ősosztálya az object.
Az osztályoknak lehetnek adattagjai (slots) amelyek beállító és lekérdező metódusokon (setter method illetve getter method) keresztül érhetünk el. A lekérdező metódus visszatérési értéke valamelyik adattag értéke lesz, a beállító metódus pedig megváltoztatja valamelyik adattag értékét. A getter illetve setter metódusok automatikusan hozzáadódnak az osztálydefinícióhoz. Nézzük a következő példát:

define class () slot horizontal; slot vertical; end class ;
A most definált osztályhoz létrejön négy generikus metódus is. A lekérdező metódusok neve horizontal illetve vertical, a beállító metódusok neve horizontal-setter illetve vertical-setter. Most megmutatjuk hogyan használhatjuk őket. A következő két sor ekvivalens, mindkettő megadja a pont vizszintes koordinátáját:

horizontal(a-point); a-point.horizontal;

A következő három sor szintén ekvivalens. Mindhárom beállítja a vízszintes koordináta értékét 10-re.

horizontal-setter(10, my-point); horizontal(my-point) := 10; my-point.horizontal := 10;

A setter metódus a beállított új értékkel tér vissza.

Egy adattag (slot) megadásakor a következő lehetőségeink vannak:
  • definiálhatunk kezdeti értéket

  • definiálhatunk egy init-kulcsszót. Ennek a segítségével "legyárthatunk" valamilyen értéket egy adattagnak, amikor egy új példány létrejön.

  • Meghatározhatjuk a memóriahasználatot (minden példányhoz újabb memóriaterületet foglaljon le vagy valamilyen egyéb módon tároljuk)

  • Egy adattagot konstansként is definiálhatunk. Ekkor nem jön létre setter metódus.

  • Megadhatjuk az adattag típusát, ekkor az adattag csak a megadott típusú értéket veheti fel.