A Kempelen Farkas Digitális Tankönyvtár/vagy más megjelenítő által közvetített digitális tartalmat a felhasználó a szerzői jogról szóló 1999. évi LXXVI. tv. 33. paragrafus (4) bekezdésében meghatározott oktatási, illetve tudományos kutatási célra használhatja fel. A felhasználó a digitális tartalmat képernyőn megjelenítheti, letöltheti, arról elektronikus adathordozóra vagy papíralapon másolatot készíthet, adatrögzítő rendszerében tárolhatja. A Kempelen Farkas Digitális Tankönyvtár/vagy más megjelenítő weblapján található digitális tartalmak üzletszerű felhasználása tilos, valamint kizárt a digitális tartalom módosítása és átdolgozása, illetve az ilyen módon keletkezett származékos anyag további felhasználása.

2.2.4. Az objektum-változó

Eddigi vizsgálataink során megállapodtunk, hogy az objektum és a példány kifejezéseket szinonimaként használhatjuk. Vagyis az objektumon egy konkrét osztály konkrét példányát értettük, ami egy önálló létező egyed, amelynek viselkedését a típusa illetve osztálya határozza meg, az állapota pedig a kapott üzeneteknek megfelelően változik.

A programozásban használatos változó (variable) olyan elem, amely alkalmas érték befogadására. Ha az objektumot, a példányt, egy konkrét értéknek tekintjük, – és miért ne tennénk ezt – akkor jogos igényünk támadhat az objektum hordozására alkalmas változó bevezetésére. Az objektum-változó olyan szerkezet, amely objektum-példányt tartalmaz. Mivel az objektumot a neki küldött üzenetekkel érhetjük el, az objektum-változónak küldött üzenetet az általa éppen tartalmazott objektum kapja meg.

Az objektum-változó bevezetése kapcsán két további problémakörrel kell foglalkoznunk. Az egyik, hogy egy objektum-változó milyen objektum-értékeket vehet fel, a másik pedig az, hogy egy objektum-változónak milyen üzeneteket küldhetünk.

A programozási nyelvekben a változók általában statikusan tipizáltak. Ez azt jelenti, hogy a program forrásszövegében meghatározzuk (definiáljuk), hogy egy változó milyen típusú, azaz meghatározzuk a felvehető értékek halmazát. A változó típusa tehát a program fordításakor már ismert, és ettől kezdve rögzített. Ezt követően a típuskorlátozás betartása a programnyelvekben különböző. A PASCAL például szigorúan típusos, ami annyit tesz, hogy nem ad nyelvi eszközöket a korlátozások átlépésére. Természetesen kellő ügyességgel, – a konkrét implementáció eszközeit vagy a variálható rekordot kihasználva – a szabályok átléphetők. Ezzel szemben a C kevésbé szigorúan típusos, mert nyelvi eszközt ad (type casting) a korlátok megkerülésére.

A statikusan tipizált változók használatának előnye, hogy a programozási nyelvekben egyszerűen és hatékonyan implementálhatók a változókat kezelő műveletek. A tipizálás statikussága természetesen független attól, hogy a változó számára mikor foglaltunk helyet a memóriában.

A dinamikusan tipizált programnyelv a második és harmadik generációs nyelvek között meglehetősen ritka, de a negyedik generációs adatbázis-kezelő nyelvek jellegzetesen ilyenek. A dinamikus tipizálás lényege, hogy a változónak nincs előre meghatározott típusa, futás közben tetszőleges értéket felvehet. Ezek az értékek különféle típusúak lehetnek. Úgy is fogalmazhatunk, hogy ezek típus nélküli változók. A szabadság ára, hogy egy típus nélküli változót elég körülményes implementálni. Emellett a változón értelmezhető műveletek ellenőrzött megvalósítása is problematikus.

A változón végrehajtható műveleteket (a változóknak küldött üzeneteket) meghatározhatja maga a változó, vagy a változóban tárolt érték. A művelet és a változó kapcsolódását kötésnek (binding) nevezzük.

Statikus kötés esetén a változón értelmezett műveleteket – objektum-változó esetében a metódusokat – a változó típusa határozza meg. Ez történik a hagyományos programnyelvekben. A fordítóprogram a változó típusának ismeretében ellenőrzi, hogy a kijelölt művelet az adott változón végrehajtható-e, és ha igen, generálja a megfelelő kódot. Például a

a + 8

művelet eredményének típusát és a létrejövő kódot attól függően állítja elő, hogy milyen az a változó típusa. Más lesz a kód integer és más real változó esetén.

Dinamikus kötés esetén a műveletet meghatározó tényező a változó által hordozott érték. Az objektum-változók esetén ez azt jelenti, hogy értékadáskor a műveleteket végrehajtó metódusok is cserélődnek. A változóval végzendő művelethez tehát most, futási időben rendelődik hozzá a műveletet végrehajtó eljárás (metódus) kódja. Ha korrekt módon akarunk eljárni, akkor bármiféle, a változóra kijelölt művelet végrehajtása előtt meg kell kérdeznünk a változót, hogy éppen milyen értéket tárol. Hiszen az sem biztos, hogy a végrehajtani kívánt művelet egyáltalán értelmezett a változóban éppen tárolt értékre (megérti-e a változóban tárolt objektum az üzenetet). Így érthető, hogy a dinamikus kötés implementálása lényegesen bonyolultabb a statikusnál.

A tipizálást és a kötést együttesen vizsgálva az eredmény az alábbiakban foglalható össze:

  • Statikus tipizálás – statikus kötés

    Megfelel a hagyományos programnyelvekben szokásosan implementált megoldásnak. A változónak típusa van és ez a típus meghatározza mind a változó értékkészletét, mind pedig a változón végrehajtható műveletet. Elviekben a változó lehet objektum-változó, de az ilyen nyelveket nem tekintjük objektumorientáltnak.

  • Dinamikus tipizálás – statikus kötés

    Azzal a meglehetősen furcsa helyzettel kerülünk szembe, hogy a változóba tetszőleges értéket – objektumot – helyezhetünk el, ugyanakkor a végrehajtható műveleteket – metódusokat – a változó nem létező típusa határozza meg. Ez az eset nem értelmezhető.

  • Dinamikus tipizálás – dinamikus kötés

    A változó tetszőleges értéket felvehet és a végrehajtható műveleteket az érték határozza meg. Ez a koncepció nagyon rugalmas, az objektumorientáltság dinamizmusa érvényre jut, de nehéz implementálni. A Smalltalk programnyelv ilyen.

  • Statikus tipizálás – dinamikus kötés

    Látszólag nincs sok értelme annak, hogy egy változóba elhelyezhető értékek típusát megkössük, ugyanakkor a végrehajtható műveleteket az értékekhez kössük. Ha szigorúan betartjuk a tipizálást, akkor ez így igaz. Ha azonban felhasználjuk a típusok kompatibilitásával kapcsolatos korábbi eredményeinket és a kompatibilitás reláció mentén felpuhítjuk a kemény típuskorlátozást, kijelentve, hogy egy adott típusú változó a vele kompatibilis típusok értékeit is felveheti, akkor már nagy jelentősége lehet ennek az esetnek. A tipizálás-kötésnek ezt a párosát gyakran implementálják programozási nyelvekben, így a C++-ban is.

Az objektum-változók bevezetése azzal a szabadsággal, hogy egy változóban a saját típusával kompatibilis típusú objektum is elhelyezhető – a polimorfizmus jelentését is kiteljesíti. Amennyiben az üzenetet a változónak küldjük, azt a változóban éppen jelenlevő objektum kapja meg, így előállhat az a helyzet, hogy valóban nem tudható előre, hogy milyen típusú objektum metódusa hajtódik végre (de a kompatibilitás miatt a művelet értelmezhető lesz).

Miután megismerkedtünk az alapfogalmakkal, a következő fejezetben azt vizsgáljuk, hogy egy valóságos vagy elképzelt rendszert hogyan modellezhetünk objektumokkal.