1 / 66

Absztrakt adattípusok

Absztrakt adattípusok. kAkAÓ 2004. Objektumorientált programozás. In: Nyékyné Gaizler Judit (szerk.): Programozási nyelvek, Kiskapu, Budapest, 2003. pp.333-350. A programozási nyelvek fontos feladata a használt programozási módszertanok aktív támogatása. Elvárások a programnyelvekkel szemben:

gudrun
Download Presentation

Absztrakt adattípusok

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Absztrakt adattípusok kAkAÓ 2004. Objektumorientált programozás. In: Nyékyné Gaizler Judit (szerk.):Programozási nyelvek, Kiskapu, Budapest, 2003. pp.333-350.

  2. A programozási nyelvek fontos feladata a használt programozási módszertanok aktív támogatása. Elvárások a programnyelvekkel szemben: 1. Modularitás: az egyes típusokat önálló fordítási egységekben lehessen megvalósítani. Ezek legyenek újrafelhasználhatóak, fejleszthesse más-más ember őket. 2. Egységbezárás (encapsulation): a nyelv kezelje összetartozó egységként a típusértékhalmazt és műveleteit. 3. Az ábrázolás elrejtése: az adott típus használója csak a specifikációban megadott tulajdonságokat használhatja ki. Ezért lehet változtatásokat végrehajtani úgy, hogy az ne érintse a hierarchia más lépcsőit. 4. A specifikáció és az implementáció szétválasztása külön fordítási egységbe lehetővé teszi, hogy az adott típust használó más modulok a típusspecifikáció birtokában elkészíthetők, függetlenül a megvalósítástól.

  3. 5. A modulfüggőség kezelése: a fordítóprogram maga kezelje a modulok közötti kapcsolatokat (egyik használja a másikat stb.) 6. Konzisztens használhatóság: a felhasználói és beépített típusok ne különbözzenek a használat szempontjából. 7. Általánosított programsémák támogatása: a programozó minél általánosabban írhassa meg programjait. A nyelv adjon lehetőséget az ismétlések minimalizálására, mert ez javítja a kód olvashatóságát és karbantarthatóságát.

  4. Modularitás. A modern nyelvekben a modulokra bontás alapja a típusokra bontás, azaz egy modul egy típust valósít meg. A modulok határai gyakran a láthatósági határokat is jelentik, gyakran a modulok kifelé korlátozzák a bennük definiált adatok láthatóságát. Egységbezárás. Lényege, hogy a típusokat a rajtuk értelmezett műveletekkel együtt, egységként használja. Azok az az alprogramok jogosultak egy típus belső szerkezetéhez hozzáférni, amelyek a típus műveleteit valósítják meg, azaz részei az egységbezárásnak. Az ún. öröklődés során a származtatott típus örökli az őstípus primitív műveleteit (ezek azok, amelyek a típussal „egységbe vannak zárva”). A C++-ban például ezek a műveletek az osztály névterében definiált műveletek.

  5. Az ábrázolás elrejtésének támogatására a nyelvek az összetett típusok komponenseinek láthatóságát gyakorta szintekre bontják, amely szintek meghatározzák, hogy pontosan kik férhetnek hozzá az adott komponenshez. Persze nem minden nyelvben: például C, Pascal vagy Modula nem rendelkezik ilyen szabályozással. Általában 3 szintet szoktak az OOP nyelvekben megkülönböztetni: Nyilvános (public) – az adott komponens mindenki számára hozzáférhető Védett (protected) – az adott komponens csak a leszármazottak számára látható (csak az öröklődést támogató nyelvekben) Privát (private) – az ábrázolás teljesen rejtett része, csak a műveletek megvalósításában használható komponensek. Ezt a 3 szintet használja pl. az ADA 95 vagy a C++, a Java és az Eiffel több szintet tesz lehetővé.

  6. A típusspecifikáció és a megvalósítás szétválasztása külön fordítási egységbe az alábbi előnyökkel jár: • Segít abban, hogy az egyes modulok egymástól függetlenül elkészíthetőek legyenek, • A típus használatához szükséges összes információ elkülönülten is rendelkezésre áll, így a megvalósítás lefordított állapotban is szállítható. • Ha a specifikációt és az implementációt két fordítási egységre bontjuk szét, gondoskodni kell arról, hogy csak a specifikációs rész birtokában a fordító program képes legyen a szükséges memóriafoglalást meghatározni. • C és C++ fejállományok (header fájlok) • A C/C++ nyelvekben a specifikációt fizikailag be kell másolni minden olyan fordítási egysége, amely az adott típust használni akarja. A specifikáció egy külön speciális forrásfájlban (header fájl) leírható, és ezt az előfordító emeli be a megfelelő fordítási egységbe.

  7. A programok legmagasabb szintű építőkövei a modulok. A programok működése ezen modulok interakciója. Minden modul igényel szolgáltatásokat és segítségükkel más szolgáltatásokat valósít meg. A modulok között egyfajta függőség alakul ki, például egy megváltozott modul miatt más modulok újrafordítása is szükségessé lehet. C++-ban ennek a kezelése a programozó feladata: minden fordítási egységet a programozónak külön kell kezelnie. Erre való a make. Maga a nyelv azonban nem nyújt támogatást. Az ADA nyelvben a with segítségével meg lehet adni, hogy a szóbanforgó modul milyen más fordítási egységektől függ. Így a modul lefordítása előtt mindazon modulok specifikációs részének lefordítására sor kerül – ha szükséges – amelyektől ez a modul függ.

  8. Azonosító túlterhelése (overloading). Egy azonosító túlterhelése azt jelenti, hogy a programszöveg egy adott pontján az azonosítónak több definíciója is érvényben van. Ilyenkor a fordító a hivatkozási környezetből dönti el, hogy a több lehetséges értelem közül melyiknek megfelelően használja az adott azonosítót. Példa: a + operátor mást jelöl a 3+4 illetve a 3.13+4.2 kifejezésekben. A fordítóprogram ilyenkor az operandusok típusa alapján határozza meg, hogy a + műveletnek mit kell csinálnia. Csinálhat-e ilyet a programozó is? Azaz lehetséges-e, hogy egy, a programozó által definiált azonosító egyszerre több definícióval bírjon, melyek közül a fordító az argumentumok típusa alapján választja ki a ténylegesen végrehajtandó példányt. Nem számít túlterhelésnek, ha egy leszármaztatott osztály megváltoztatja egy ősosztályban deklarált művelet definícióját: ezt felüldefiniálásnak nevezzük. Ebben az esetben a hivatkozáshoz tartozó tényleges definíció nem fordítási időben (statikusan), hanem futási időben (dinamikusan) választódik ki. Ezt a jelenséget dinamikus összekapcsolásnak nevezzük (late binding).

  9. A túlterhelés speciális esete az operátor túlterhelés, amikor egy nyelv operátorait (+, –, *, /, = , <, >, sizeof, new stb.) terheljük túl. Ha pl. definiálunk egy mátrix típust, szeretnénk a mátrixok szorzását is *-gal jelölni.

  10. Típussal való paraméterezés kAkAÓ 2004. Objektumorientált programozás. In: Nyékyné Gaizler Judit (szerk.):Programozási nyelvek, Kiskapu, Budapest, 2003. pp.353-388.

  11. A programfejlesztés során gyakran merül fel annak igénye, hogy általánosan megfogalmazott, széles körben alkalmazható megoldásokat adjunk. Megfelelő paraméterek megválasztásával az alprogramok erre lehetőséget adnak. Az alprogramok paraméterei nem lehetnek típusok, pedig a különféle típusokon megadott hasonló feladatokat hasznos lenne egyetlen alprogrammal megoldani. A típusparaméterrel ellátott alprogramokat polimorfnak, azaz többalakúnak nevezzük. Előfordulhat az is, hogy a különböző típusokhoz különböző implementáció tartozik. Példa: különböző alaptípusú tömök rendezése egyetlen rendező alprogrammal, amely az elemtípussal van paraméterezve.

  12. C++-ban a template szerkezettel lehet megoldani a feladatot: template <classElem> voidrendez(vector<Elem>& v){ constsize_tn=v.size(); for (intgap=n/2; 0<gap; gap /= 2;{ for (inti=gap; i<n; i++){ for (intj=i – gap; 0<=j; j – =gap){ if (v[j+gap]<v[j]){ Elem temp=v[j]; v[j]=v[j+gap]; v[j+gap]=temp; } } } } } Shell rendezés tetszőleges Elem elemtípusú tömbre Elem helyére írhatunk például int-et Ha egész számokat kívánunk rendezni, vector<int> v; rendez(v); kell.

  13. Objektumorientált programozás kAkAÓ 2004. Forrás: Objektumorientált programozás. In: Nyékyné Gaizler Judit (szerk.):Programozási nyelvek, Kiskapu, Budapest, 2003. pp.391-456.

  14. A számítógépes programok segítségével az ember a valós világot próbálja modellezni. Az objektumorientált szemlélet a valóság megközelítésének és ábrázolásának egy módszere. A modellezés során a valós tárgyakat objektumokkal ábrázolja,, amelyeket állapotukkal (adataikkal) és metódusaikkal jellemez. Az OO megközelítés egy programozási szemléletmód, amelynek alapján rendszerfejlesztési módszertanokat is kidolgoztak. Ezek a módszertanoka teljes fejlesztési folyamatot átfogják: Analízis, Tervezés, Implementálás, Tesztelés, Karbantartás.

  15. Az analízis során a rendszert együttműködő objektumok összességeként modellezzük, a tervezés és az implementáció ezen objektumokat alakítjuk ki. Objektumorientáltnak nevezünk egy programot, mely egymással kapcsolatot tartó objektumok összessége, ahol minden objektumnak megvan a jól meghatározott feladata. A modellezés során az ember olyan gondolatmenetet használ, amelynek segítségével elvonatkoztat, megkülönböztet, osztályoz, általánosít, vagy leszűkít, részekre bont, kapcsolatokat épít fel.

  16. Az absztrakció az a szemléletmód, amelynek segítségével a valós világot leegyszerűsítjük úgy, hogy csak a cél elérése érdekében feltétlenül szükséges részekre koncentrálunk. Az objektumok a modellezendő valós világ egy-egy önálló egységét jelölik. Meghatározza őket belső állapotuk és a nekik küldhető üzenetekre való reagálásuk. A reagálás során az objektum belső állapota megváltozhat, illetve valamilyen műveletet végez, üzenetet küldhet más objektumoknak. Az objektumokat kategorizáljuk, a hasonlókat egy osztályba soroljuk. Az osztályozás az általánosítás és a specializálás segítségével történik: az objektumok között hasonlóságokat és különbségeket keresünk.

  17. Az osztályozás az emberi gondolkodás szerves része. Az ugyanolyan fajta adatokat tartalmazó, és az ugyanolyan viselkedés-leírással (metódusokkal) rendelkező objektumokat egy osztályba soroljuk. Az objektum-osztályok hordozzák a hozzájuk tartozó objektumok jellemzőit. Minden objektum valamilyen osztály példánya (instance), rendelkezik osztályának sajátosságaival, átveszi annak tulajdonságait az adatszerkezetekre és a műveletekre vonatkozóan. Az objektum tehát adatok (attribútumok) és műveletek (metódusok) összessége, ez utóbbiak elvégzik az objektumra szabott feladatot vagy leírják az objektum viselkedését. Attribútum a művészetben: ha egy templomi festményen valaki kulcsot tart a kezében, akkor az Péter apostol, és a művelet a kezében tartás.

  18. Az objektumoknak mindig van belső állapotuk – ezt az adatok pillanatnyi értékei jellemzik. Metódushívások után az objektumok állapota meg változhat. Az objektumok emlékeznek állapotukra és a feladatvégzési folyamat mindig egy alapértelmezett kezdőállapotból indul, és egy másik állapotba megy át. A következő állapotátmenetnél onnan folytatja a folyamatot, ahol előzőleg abbahagyta. A kapcsolatban álló objektumok kommunikálnak egymással. Ez üzenetküldés formájában történik. Az üzeneteket kívülről elérhető metódushívásokkal ábrázoljuk. Az üzenetet a megszólított objektum azonosítójával minősítjük, és lehetnek paraméterei: Obj.Üzenet (Paraméterek)

  19. Ha az objektumtól valamilyen választ várunk az üzenetre, akkor ezt a változó paramétereken keresztül vagy a metódus visszatérési értékeként kaphatjuk meg. A következőkben megnézzük, hogyan hozhatók létre osztályok és objektumok egyes programozási nyelvekben.

  20. SIMULA 67 ClassTeglalap(TeglNev, Szelesseg, Magassag); ! Osztály 3 paraméterrel TextTeglNev; RealSzelesseg, Magassag; ! Paraméterek specifikációja Begin RealTerulet, Kerulet; ! Attribútumok; ProcedureFrissit; ! Művelet; Begin Terület := Szelesseg * Magassag; Kerület := 2*(Szelesseg + Magassag); End ofFrissit; ProcedureKiir; ! Művelet; Begin OutText(”I am a Teglalap”); OutText(TeglNev); OutText(”Terulet: ”); OutFixText(Terulet,2,7); OutText(”Kerulet: ”); OutFixText(Kerulet,2,7); End ofKiir; Frissit; ! Teglalap élete; Kiir; End ofTeglalap; Létrehozás: newTeglaLap(„Kicsi”,2,3)

  21. SMALLTALK A SMALLTALK-ban minden objektum, még az osztályok is. Ez azt jelenti, hogy az osztályoknak is vannak adattagjaik és metódusaik. Hozzunk létre egy Szamla osztályt egy Egyenleg nevű adattaggal. Object subclass: #Szamla instanceVariableNames: ‘egyenleg’ classVariableNames: ‘’ poolDictionaries: ‘’ Category: nil !

  22. C++ -ban egy új osztályt így deklarálhatunk: class Teglalap{ int x, y; public: void ertekadas (int, int); int terulet() { return (x*y); } }; A Teglalap osztály két rejtett adattagja x és y. Két nyilvános metódusa van, az értékadó és a terület számító metódus. A területszámító metódust az osztály deklarációjában definiáltuk. Az értékadást az osztálydeklaráción kívül, a baloldalt látható módon adhatjuk meg. void Teglalap::ertekadas(int x1, int y1){ x = x1; y = y1; }

  23. A Teglalap osztály egy új tagjának létrehozása C++-ban statikus illetve dinamikus helyfoglalású változóként: Teglalap haz; // statikus helyfoglalású példány haz.ertekadas(5,3); int thaz = haz.terulet(); // thaz = 15 Teglalap * kert = newTeglalap; // Dinamikus helyfoglalású példány kert ->ertekadas(20,17); int tkert = kert->terulet(); // tkert = 340

  24. Az Object Pascalban egy új osztályt szintén a class kulcsszó segítségével hozhatunk létre: type TDatum = class private Ev, Honap, Nap : integer; public procedureBeallit (e,h,n: integer); functionSzokoev: boolean; … end. Az objektum példányok létrehozása dinamikusan történik, ellentétben a Turbo Pascallal, a változó deklarálása után meg kell hívnunk az osztály konstruktorát, amely lefoglalja és inicializálja a szükséges memóriaterületet (Create). A használat befejeztével a memóriaterület felszabadítása is a programozó feladata (Free).

  25. Var EgyNap : TDatum; begin … EgyNap := Tdatum.Create; … EgyNap.Beallit(2003,4,6); { használat } … EgyNap.Free; { felszabadítás } end; Az adatmezők és a metódusok mellett az osztálytípusok tulajdonságokat (property) is tartalmazhatnak. A tulajdonság egy olyan név, amely a megadott olvasás és/vagy írás műveleteken keresztül férhet hozzá az objektum adattagjaihoz.

  26. Egységes jelölési módok: az osztálydiagram Osztály Adat Adat: típus Adat: típus= érték … metódus metódus(paraméterlista) metódus: típus metódus(paraméterlista):típus … Az osztály neve Adatok metódusok Az osztálydiagram tartalmazza az osztály nevét, az objektumok megvalósítására használt adatokat és típusukat, valamint a metódusokat. Az adatok az állapotok belső leírásai, a metódusok műveletek vagy üzenetek.

  27. Egységes jelölési módok: az objektumdiagram Obj: Osztály adat1 = érték1 adat2 = érték2 … adatn = értékn Az objektum azonosítója és az osztály neve, amelynek példánya állapot példányszám Osztály Objektum példányosítás

  28. Az egyes programok objektumaira jellemző az életciklusuk: „megszületnek”, „élnek”, „meghalnak”. Az objektum kezdeti állapotát a konstruktor állítja be. Ekkor történik meg az objektum adattagjainak kezdőértékadása és az objektum működéséhez szükséges kezdeti tevékenységek végrehajtása. A nyilvános osztályok konstruktorának is nyilvánosnak kell lennie, hogy az objektumot tartalmazó program hozzáférhessen. Egyes nyelvekben destruktor is van, melyet az objektum megszűnésekor vagy a programozó, vagy a rendszer meghív és így memóriát szabadít fel.

  29. C++ példa konstruktorra classKomplex { doublere, im; public: Komplex() { re=0; im=0;} Komplex(double a, double b) {re=a, re=b;} } …..; Komplex z1; …….. Komplex z2(1,1); C++-ban egy osztály konstruktorának neve megegyezik az osztály nevével. Egy osztálynak több konstruktora lehet a függvénynév túlterhelés miatt Az objektumok felszabadítását a destruktor végzi. A destruktor neve az osztálynév elé írt ~(tilde) jellel képezhető. A statikus objektum megszűnésekor illetve a dinamikus objektum helyének felszabadításakor a destruktor automatikusan meghívódik. Paramétere nincs, mivel nem feltétlenül a programozó hívja meg.

  30. Object Pascal type Tdatum = class private ev, ho, nap: integer; public constructorCreate(e,h,n: integer); … end; constructorTdatum.Create(e,h,n: integer); Object Pascalban egy osztályhoz több különböző konstruktort hozhatunk létre, ezek neve tetszőleges lehet és akármennyi paraméterük lehet. Deklarálásukkor a constructor kulcsszót kell használni. A TObject osztály (minden osztály őse) konstruktorának neve Create, ezt szokás használni. Object Pascalban a konstruktort az objektumpéldány használata előtt külön meg kell hívni. Az alapértelmezett destruktor a Destroy, akkor híjuk meg, ha már nincs szükségünk az objektumra.

  31. Eiffel classKOMPLEX creation ertekadás feature valos, kepzetes: REAL feature ertekadas(r,i: REAL)is do valos := r; kepzetes:=i end; end Eiffelben a konstruktort a creation záradékkal lehet megadni. Az alábbi utasítás hatására létrejön a z-hez rendelt objektum, melynek kezdeti értéket is adunk. z: KOMPLEX; !!z.ertekadas(1,0); Eiffelben nincs explicit destruktor. Amikor egy objektumra már nem hivatkozik többé program, egy automatikus szemétgyűjtő eljárás megszünteti az objektumot (garbage collection)

  32. A példányosítás és a Self Delphi: Self; Java, C++:this; A példányosítás során létrejön az objektum és utasítások elvégzésére felszólító üzenetekre vár. A metódusokat az osztályhoz rendeljük és nem másoljuk be minden újonnan létrehozott objektumba: a metódusok az osztály leíró részében szerepelnek csak, az objektumban nem. Az objektumok tudják, hogy melyik osztályhoz tartoznak, és ennek alapján történik a metódusok kiválasztása. Kérdés: ha több objektumot példányosítunk egy osztályból, honnan tudjuk, hogy melyik objektum hívta az adott metódust, azaz a metódusnak melyik objektum adataival kell dolgozni? Erre van egy speciális hivatkozás, amely mindig a metódust meghívó aktuális objektumpéldányra mutat. Ez Delphiben a Self, más nyelvekben this. A Self rámutat arra az objektumra, amellyel a metódusnak dolgoznia kell.

  33. Delphi példa a Self használatára procedure TCurveFittingForm.Timer1Timer(Sender: TObject); begin Timer1.Enabled:=False; { <-- stop timer } With StockPrice do Begin Delete(0); { <-- remove the first point } { Add a new random point } AddXY( XValues.Last+1, (YValues.Last/YValues.Multiplier)+(Random(ChartSamplesMax)-(ChartSamplesMax/2)), '',clTeeColor); Chart1Zoom(Self); { <-- recalculate Curve !!!! } end; Timer1.Enabled:=True; { <-- restart timer } end;

  34. Megjegyzések a 7 elvárás és az OOP kapcsolatáról Egységbezárás. Számos OOP nyelvben az egységbezárás a korábbi struktúra, ill. rekord adattípusát (struct, record) továbbfejlesztve vezeti be az osztálytípust (class). Ada95-ben az egységbezárás csak közvetetten valósul meg. Az Ada83 rekord fogalmát bővítették ki, de ezen rekordok csak az osztály attributumait tartalmazzák, a műveleteket nem. Így az egységbezárás csak a tagged rekordtípus (tag=cédula, címke) és a műveletek egy modulba (package) helyezésével valósítható meg.

  35. Adatrejtés és interfész • Az egységbezárás az alábbi szabályok segítségével valósul meg: • Az objektum csak olyan üzenetekre reagál, amelyekre megtanították • Az ojektumot csak az interfészen keresztül lehet elérni • Az objektum interfésze alehető legkisebb legyen. • Módszertani követelmény, hogy az adatok csak a metódusokon keresztül legyenek elérhetők. Ha a nyelvek egy része ad is lehetőséget az adatok közvetlen elérésére, ezt inkább mellőzzük. • Az interfész definiálása a programozó feladata. Ezt úgy tudja elvégezni, hogy megadja az objektum osztályában a külvilág számára elérhető metódusokat, esetleg az adatok egy részhalmazát is: ezek nyilvánosak (public). A rejtett (private) adatokat és metódusokat csak az adott objektum használhatja. • Egy adat nyilvános volta ideális esetben csak lekérdezési lehetőséget jelent, felülírási, megváltoztatási lehetőséget nem így van például az Eiffelben.

  36. Elérhetőség a C++ -ban class A { int i; public: voidset_i (intn) {i=n}; intget_i() {returni;}; }; class A1 { privateint i; public: voidset_i (intn) {i=n}; intget_i() {returni;}; }; class A2 { public: voidset_i (intn) {i=n}; intget_i() {returni;}; privateint i; }; A C++ -ban az osztályok definíciójában a láthatóság osztályszintű, azaz az azonos osztályba tartozó objektumok el tudják érni közvetlenül egymás rejtett adatait is. Osztályok esetén a privateaz alapértelmezés, és a nyilvános és rejtett részek tetszés szerinti sorrendben megadhatók. Ezért a baloldali definíciók egyenértékűek.

  37. Adatrejtés Object Pascalban Az Object Pascalban private kulcsszóval az objektumok belső használatú részeit jelöljük, de ezek ténylegesen csak az osztályt deklaráló egységen (forrásfájlon) kívül nem láthatóak. Így tehát a módszertani elvárások szerinti adatrejtést csak akkor tudjuk megvalósítani, ha MINDEN OSZTÁLYT KÜLÖN FÁJLBA TESZÜNK. A szokásos módon public jelöli a mindenki által látható részeket. Azalapértelmezés a publishedláthatóság. A published ugyanolyan láthatóságú, mint a public, a különbség az, hogy futásidejű típusinformáció (RTTI=RunTime Type Information) generálódik minden published típushoz. Így egy applikáció dinamikusan lekérdezheti egy objektummezőit és tulajdonságait, valamint megtalálhatja metódusait. Az RTTI technológia használatos a tulajdonságok kezelésére form fájlok mentésekor és betöltésekor, valamint az eseménykezelő (event handler) metódusok és az események összerendelésekor.

  38. Láthatóság Eiffelben Az Eiffel nyelv fejlesztői az ún. szelektív láthatóságot valósították meg. Ez azt jelenti, hogy az osztály minden egyes jellemzőjére (feature) külön megadható, hogy mely osztályok érhessék el. Eiffelben a láthatóság objektum és nem osztály szintű, így ha azt akarjuk, hogy az adott osztály más példányai is elérhessenek egy bizonyos jellemzőt, akkor ezt explicite meg kell adnunk a láthatósági szabályokban. A láthatóságra vonatkozó kívánalmakat úgy adhatjuk meg, hogy a feature kulcsszó után kapcsos zárójelek között felsoroljuk azon osztályoknak a nevét, melyek számára az itt következő jellemzőket láthatóvá kívánjuk tenni. A mindenki számára látható az ANY (ez alapértelmezés, így elhagyható), az adott objektumon kívül seholsem látható a NONE szóval adható meg.

  39. Eiffel láthatósági példa classC feature {ANY} x : T; -- minden osztály láthatja feature{C} y: U; -- a C osztály példányai láthatják feature{NONE} z: V; -- csak az adott objektumon belül látható end-- class C

  40. Friend metódusok, osztályok C++ -ban A C++ -ban egy másik osztály metódusainak meg lehet engedni, hogy bizonyos esetekben hozzáférjen az objektum adataihoz, és így ismeretségi kapcsolatokat lehet megvalósítani. Ezen metódusokat barát (friend) metódusoknak nevezzük. Ezek nem az osztály objektumainak küldött üzenetek, hanem külső függvények, így nem érvényes az, hogy a Self segítségével látják az objektumot. Ennek megfelelően az aktuális objektumot is meg kell adni egy további paraméterben. Az is megengedett, hogy egy osztály barátnak nyilvánítson egy másik osztályt. Ekkor a barát osztály metódusai elérhetik az illető osztály privát adatait. friend Eljárásnév (par_lista); friend Osztály.Metódus(par_lista); friend Osztálynév;

  41. Az osztályok belső állapotát leíró adatokat osztályadatoknak hívjuk. Ezek az adatok az osztályról tárolnak információkat és így nem feltétlenül változnak az egyes objektumok állapotváltozásaival együtt. Helyük az osztály helyfoglalásakor foglalódik le és az osztály helyének felszabadulásakor szabadul fel. Egyes nyelvekben (C++, Java, C#) ezek az osztályváltozók ún. statikus adatok (static) és az osztály objektumai is tudják használni őket. Egy adott osztályváltozóból mindig pontosan egy létezik és az osztály minden egyes példánya ezen „osztozik”. Például egy osztály esetén egy osztályváltozóban számolhatjuk az ehhez az osztályhoz létrehozott objektumokat.

  42. classDatum{ intev, ho, nap; staticDatum alapert_datum; // osztálymetódus public: Datum (intee=0, inthh=0,intnn=0); //… static voidbeallit_alapert(int,int,int); }; Datum::Datum(int ee, int hh, int nn){// :: scope access operátor, a globálisra vonatkozik // ha paraméter nélküli konstruktor hívás történik, akkor az alapert_datum értéket kapja // az új objektum ev = ee ? ee : alapert_datum.ev; // ha ee=true vagy nem 0, akkor ee, egyébként … ho = ho ? ho : alapert_datum.ho; nap = nap ? nap : alapert_datum.nap; }; void Datum::beallit_alapert(int e, int h, int n) { // a statikus adattag értékének megváltoztatására Datum::alapert_datum = Datum(e,h,n); }; Datum Datum::beallit_alapert(2003,3,16); // a statikus adattag definiálása

  43. Osztálymetódus Object Pascalban Az object Pascalban azt, hogy egy műveletet osztálymetódusként akarunk használni, az osztály definíciójában a class kulcsszóval jelezhetjük. B az osztály objektumainak metódusa, míg ObjSzam az A osztálymetódusa. type A = class procedureB; class functionObjSzam: integer; end; implementation varObjSz: integer=0; class functionA.ObjSzam:integer; begin Result := ObjSz; end; Az ObjSzamosztálymetódus törzsében levő ObjSz rejtett változót az osztály összes objektuma és az osztálymetódus(ok) közösen használhatják.

  44. Az osztálydiagramoknál is szokás feltüntetni, ha egy adat osztályadat, vagy ha egy metódus osztálymetódus, ami az adat- vagy metódusnév elé írt C betű jelez. A + jel a nyilvános, a – jel a rejtett elérést jelenti.

  45. Öröklődés Az OO megközelítés a valós világ objektumait – tulajdonságaik alapján – osztályokba sorolja. Minden kategóriának számos alkategóriája lehet, és ezen kategóriák alatt további alkategóriák vannak. Az alosztályok létrehozásakor mindig támaszkodunk annak az osztálynak a tulajdonságaira, amelyiknek az új alosztály része: az alosztály örökli az ősosztály tulajdonságait. Az ősosztály is lehet, hogy valamely más osztály alosztálya, tehát tulajdonságainak egy részét örökölte. A specializációt úgy valósítjuk meg, hogy az egyes alosztályokba új attribútumokat vezetünk be. Például, ha az Emberek osztályt az Élőlények osztályból származtatjuk, akkor bevezethetjük például az anyanyelv attribútumot, amely csak az Emberek alosztály tagjaira érvényes.

  46. Lehetőséget kell biztosítani arra is, hogy az egyes alosztályokban bővítsük a műveletek halmazát olyan műveletekkel, amelyek az ősben nincsenek. Az altípusképzés során megengedjük a változtatást is, azaz hogy az új osztályban egyes műveletek átdefiniálhatók legyenek, implementációjuk, esetleg specifikációjuk is különbözzön az ősosztálybeliétől. Dinamikus összekapcsolás kell, hogy lehetőséget adjon arra, hogy a változó aktuális típusa – futásközben – határozza meg a művelet végrehajtandó implementációját. A műveletek átdefiniálása nem történhet tetszőlegesen (erre még visszatérünk). Ezt a műveletet specifikáció öröklésnek nevezzük. Egy meglevő osztályt bármikor felhasználhatunk más osztályok definiálására azzal a céllal is, hogy a már meglévő kódot újra fel tudjuk használni. Ez akkor valósul meg, ha a leszármaztatott osztály implementációjában rejtetten használjuk az ősosztályt. Ezt nevezhetjük újrafelhasználó öröklésnek vagy implementációs öröklődésnek.

  47. Az öröklődés lehet egyszeres vagy többszörös. Egyszeres öröklődésről akkor beszélünk, ha a leszármaztatott osztálynak pontosan egy közvetlen ősosztálya van. Többszörös öröklődés esetén a leszármaztatottnak legalább két közvetlen ősosztálya van. A leszármaztatott osztály mindig örökli az ősosztály adatait és metódusait. A többszörös öröklődés esete gondot okozhat, ha például két közvetlen ősosztályban is szerepel egy-egy ugyanolyan nevű adat vagy metódus, akkor a leszármaztatott osztályban ez többértelműséghez vezethet (erre visszatérünk).

  48. C++ példa öröklődésre classSikidom{ protected: // származtatott osztályokban látható int szelesseg, magassag; public: voidbeallit_ertekek (inta, intb){ Szelesseg=a; magassag=b;} }; classTeglalap: publicSikidom{ public: intterulet(){ return (szelesseg*magassag);} }; classHaromszog: publicSikidom{ public: intterulet(){ return (szelesseg*magassag/2);} }; A Teglalap és a Haromszog osztály is rendelkezik a Sikidom osztályban bevezetett adattagokkal és metódussal. A terulet() metódus új mindkét osztályban, más-más módon definiálva.

  49. A C++ megengedi a többszörös öröklődést is, ha például az előzőeken túl bevezetjük az Egyenlooldalu osztályt is, akkor a Negyzet osztály lehet ennek és a Teglalap osztálynak is a leszármazottja. classEgyenlooldalu{ public: bool e; }; classNegyzet: publicTeglalap, public Egyenlooldalu{ Negyzet(){ e = true;} };

  50. Öröklődés az Object Pascalban type Tallat = class public function eszik: string; private fajta: string; end; TKutya = class(TAllat) public function ugat: string; end; varKutya1 : TKutya; begin {….} writeln(Kutya1.eszik); {….} writeln(Kutya1.ugat); end. Az Object Pascal az egyszeres öröklődést támogatja, interfészek segítik a többszörös öröklődést (ld. később). A TAllat leszármazottja a TKutya, itt vezetjük be a kutyákra jellemző ugat függvényt.

More Related