• Ei tuloksia

5 TOTEUTETTU JÄRJESTELMÄ

5.1 Ajonaikainen oliomallinnusympäristö - MOS

5.1.5 Periytyminen

Tyyppimäärittely kertoo tietoalkioiden semanttiset ja fyysiset ominaisuudet. Fyysisiä ominaisuuksia varten MUST-järjestelmässä on viisi sisäänrakennettua C++-luokkaa, joiden instansseihin tietoalkioiden arvot talletetaan. Nämä luokat ovat:

e tekstityyppi, arvo on 0 - 64000 merkin mittainen merkkijono, joka ei sisällä \0 - merkkiä,

• kokonaisluku, arvoalue C-kielen long-tyypin mukainen,

• liukuluku, yleisimmin käytetty tyyppi, arvoalue on C-kielen double-tyypin mukainen,

• liukulukulista, lista liukulukuja, listan pituus voi olla 1 - 16000 lukua ja

• levylle talletettu liukulukulista, jossa listan pituus voi olla 1 - 16000 lukua, mutta keskusmuistia varataan vain yhden osoittimen (4 tavua) verran.

Fyysisiä ominaisuuksia voi vaihtaa ainoastaan vaihtamalla tietoalkion tyypin kokonaan toiseen. Semanttisiin ominaisuuksiin kuuluvat mm. aikajakson alkupäivämäärä ja periodin pituus. Myös lukulistan pituus on muutettavissa dynaamisesti.

Attribuuttien oletusarvot

Jokaisella instanssilla on oma kopio jokaisesta attribuutistaan ja sen arvosta. Instanssin luomishetkellä kaikki attribuutit alustetaan luokasta haettujen oletusarvojen mukaisiksi.

Oletusarvoihin myöhemmin tehdyt muutokset eivät päivity instanseille. Erillisiä luokkakokohtaisia muuttujia voidaan toteuttaa laskentasääntökielen avulla.

5.1.5 Periytyminen

Attribuuttien periyttäminen alaluokille ja instansseille on luokkahierarkian tärkein tehtävä. Periyttämisalgoritmej a tarvitaan kaikissa seuraavissa oliomallinnuksen tilanteissa:

• Luokalle lisätään tai siltä poistetaan yläluokka,

e Instanssin luokka vaihdetaan.

e Attribuutti luodaan tai tuhotaan.

• Attribuutin laskentasääntö luodaan, tuhotaan tai sitä muutetaan.

• Attribuutin määrittely siirretään luokkahierarkian luokasta toiseen.

Periyttäminen voidaan nähdä keinona pitää oliomallin tilaa konsistenttina.

Konsistentissa tilassa oliomallissa pätevät seuraavat aksioomat:

• Kaikki luokasta löytyvät attribuutit löytyvät myös kaikilta kyseisen luokan alaluokilta.

• Jokainen luokan attribuutti, joka ei esiinny jossain luokan yläluokista, on luotu suoraan kyseiseen luokkaan.

• Instanssin attribuuttien joukko on täsmälleen sama kuin vastaavan luokan attribuuttien joukko.

CLOS-j ärjestelmässä periytymiseen liittyvät tilanteet on määritelty kieleen kuuluvien protokollien (Metaobject Protocols) avulla. Esimerkiksi luokan luominen tehdään oheisten Class Initialization ja Class Finalization -protokollien mukaisesti [Раер93].

Metaobjektiprotokollat mahdollistavat CLOS-järjestelmän käyttäytymisen muuttamisen metaobjektien tasolla. Käytännössä ohjelmoija voi korvata tai laajentaa jonkun proto­

kollan yksittäisen toiminnon tai useamman toiminnon käsittävän kokonaisuuden. Proto­

kollat esitetään tässä vertailuksi MO S-kirjaston protokollille.

DEFCLASS ~~

1. Syntax error checking 2. Canonicalize information 3. Obtain class metaobject

3.1 Find or make instance of proper class metaobject class 3.2 (Re)initialize the class metaobject

3.2.1 Check compatibility with superclasses

3.2.2 Determine proper slot-definition metaobject class 3.2.3 Create and initialize the slot-definition metaobject 3.2.4 Maintain the 'subclasses' lists of superclasses

3.2.5 Initialize inheritance finalization, if appropriate_______________________

FINALIZE-INHERITANCE

1. Compute the class precedence list

2. Resolve conflicts among inherited slots with the same name 2.1 Determine proper effective slot definition metaobject class 2.2 Create the effective slot definition metaobjects

2.3 Initialize the effective slot definitions

MOS-kirjastossa periytymisominaisuudet on toteutettu periatteessa samalla tavalla.

Koska MOS-metaluokat ovat C++-kielisiä, on niihin tehtävät muutokset kirjoitettava suoraan C++:lla. Protokollat muodostuvat näinollen C++-fimktioiden kutsu- järjestyksistä. MOS-protokollat on pyritty jakamaan mahdollisimman pieniin atomaarisiin osiin. Attribuutteja sisältävän luokan luomiseen tarvitaan MOS-kirjastossa useita kutsuja, kun esimerkiksi CLOS-kielessä riittää yksi defclass-komento.

LISAA-ALALUOKKA

1. Tarkista, ettei lisäys aiheuta sykliä perintähierarkiaan.

2. Päivitä ala- ja yläluokkien listat molemmissa luokissa.

3. Luo kaikki tarvittavat yläluokan attribuutteja vastaavat uudet attribuutit rekursiivisesti uusiin alaluokkiin ja niiden instansseihin.

4. Päivitä kaikki yläluokan aiheuttamat muutokset alaluokkien vanhoihin attribuutteihin.

POISTA-ALALUOKKA

1. Päivitä ala- ja yläluokkien listat molemmissa luokissa.

2. Poista yläluokan attribuutteja vastaavat attribuutit rekursiivisesti vanhoista alaluokista ja niiden instansseista, mikäli attribuutteja ei ole moniperitty muiden

luokkahierarkian reittien kautta. ______

VAIHDA-INSTANSSIN-LUOKKA

1. Lisää instanssi uuden luokan instanssien listaan ja poista se vanhan luokan instanssien listasta.

2. Aseta instanssin luokaksi uusi luokka.

3. Luo kaikki sellaiset attribuutit, jotka on määritelty uudessa luokassa, mutta joita ei oltu määritelty vanhassa luokassa.

4. Päivitä kaikki luokan aiheuttamat muutokset instanssin vanhoihin attribuutteihin.

5. Poista sellaiset vanhasta luokasta perityt attribuutit, jotka eivät periydy uudesta luokasta.

LISAA-ATTRIBUUTTI-LUOKKAAN

1. Mikäli attribuuttia ei jo ole luotu tähän luokkaan, luo attribuutti rekursiivisesti tähän luokkaan, sen instansseihin ja alaluokkiin.

PÄIVIT A-ATTRIBUUTTI-LU OKAS SA

1. Mikäli päivityksen aloittaneen luokan attribuutti on ensimmäinen luokkien perintäjärjestyslistassa, päivitä attribuutin ominaisuudet rekursiivisesti tässä luokassa, sen instansseissa ja alaluokissa.__________________________________

POISTA-ATTRIBUUTTI-LUOKASTA

1. Mikäli attribuutin perusluokka (se luokka, jossa attribuutti alunperin luotiin) ei enää ole tämän luokan yläluokka, tuhoa attribuutti rekursiivisesti tässä luokassa, sen instansseissa ja alaluokissa.__________________________________________

LIITA-LASKENTASAANTO-ATTRIBUUTTIIN

1. Tarkasta, että sääntöä voidaan käyttää ko. attribuutin arvon laskemiseen ko.

luokassa.

2. Ota sääntö käyttöön tässä luokassa ja sen instansseissa.

3. Ota sääntö käyttöön rekursiivisesti kaikissa niissä alaluokissa, jotka eivät itse ole ohittaneet periytymistä tämän attribuutin osalta (esimerkiksi ottamalla suoraan käyttöön jonkin muun säännön)._________________________________________

SIIRRA-ATTRIBUUTTI-YLÄLUOKKAAN

1. Poista nykyisestä luokasta attribuuttia vastaava perusattribuutti.

2. Luo uusi periytynyt attribuutti poistetun tilalle ja lisää se nykyisen luokan attribuutiksi.

3. Aseta uuden periytyneen attribuutin säännöksi aikaisemman perusattribuutin käyttämä sääntö.

4. Poista yläluokkaan siirretyltä perusattribuutilta sääntö.

5. Lisää perusattribuutti yläluokan attribuutiksi.

6. Käynnistä normaali periytymisalgoritmi ikäänkuin attribuutti olisi juuri luotu yläluokkaan._________________________________________________________

SIIRRA-ATTRIBUUTTI-ALALUOKKAAN

1. Poista nykyisestä luokasta attribuuttia vastaava perusattribuutti.

2. Aseta perusattribuutin säännöksi alaluokassa olevan vastaavan periytyneen attribuutin käyttämä sääntö.

3. Poista alaluokasta periytynyt attribuutti.

4. Lisää perusattribuutti alaluokan attribuutiksi.

5. Poista attribuutti kaikista nykyisen luokan suorista instansseista.

6. Poista attribuutti rekursiivisesti kaikista muista nykyisen luokan alaluokista paitsi siitä, johon attribuutti siirrettiin._________________________________________

Alla on esimerkki MOS-protokollan 'SURRA-ATTRIBUUTTI-YLÄLUOKKAAN' toteutuksesta:

void MOSClass::promoteItem(MOSBaseltem MOSClass *superC)

{

// remove the baseitem from the items of this class removeltem(item);

// create a new inherited item to this class MOSItem *i = new MOSInheritedltem(this,item);

// set the rule in this class level to the old rule i->putRule((MOSRule*)item->getRule());

// remove the rule from the promoted (superclass) item item->removeRule(NIL);

// add the baseitem to the items of the superclass item->setParent(superC);

superC->addltem(item);

// add the item to other subclasses of supeclass superC->inheritedAttribute(CREATE_A,item);

}