Interfészek szenasi.sandor@nik.bmf.hu PPT 2007/2008 tavasz http://nik.bmf.hu/ppt 1
Témakörök Polimorfizmus áttekintése Interfészek Interfészek kiterjesztése Eseménykezelési módszerek 2
Már megismert fogalmak áttekintése Objektumorientált program felépítése Osztály, objektum Érték típus, referencia típus Öröklődés egyszeres öröklődés többszörös öröklődés Korai kötés, késői kötés Absztrakt osztály Polimorfizmus (többalakúság) módszer polimorfizmus objektum polimorfizmus Polimorfizmus a gyakorlatban pl. vizuális felület komponensei Az (egyszeres) öröklődés korlátai 3
Témakörök Polimorfizmus áttekintése Interfészek Interfészek kiterjesztése Eseménykezelési módszerek 4
Interfész fogalma Az interfészek olyan üres osztályok, amelyek nem tartalmaznak megvalósítást Interfészek néhány tipikus alkalmazása osztályok felruházása valamilyen műveletekkel (nevet rendel metódus szignatúrák egy csoportjához) többszörös öröklődés egyszerűsített megvalósítása UML jelölések <<interface>> IComperable +equals( ) +more( ) +less( ) IComperable Number +equals( ) +more( ) +less( ) interfész definíció interfész megvalósítás 5
Interfész felépítése Interfész tipikusan (nyelvtől függően) tartalmazhat metódus szignatúrát szignatúra: metódus neve + visszatérési értéke + paraméterek (interfész metódus mindig virtuális és absztrakt) konstans mezőt mivel ezek nem igényelnek objektum példányt tulajdonságot amennyiben a nyelv támogatja Interfész nem tartalmazhat konkrét metódus, tulajdonság implementációt példányszintű mezőt példányosításhoz kapcsolódó konstruktort/destruktort Különböző módosítók (láthatóság stb.) az osztályokhoz hasonló módon használhatók, bár nyelvtől függően eltérések is lehetnek 6
Interfész megvalósítása (támogatása) Interfészek önmagukban nem példányosíthatók, csak az őket megvalósító osztályokon keresztül érhetők el a műveleteik Az interfész megvalósításának lépései osztály definícióban a megvalósítandó interfészek felsorolása az interfész(ek)ben definiált metódusok implementálása Egy osztály egyszerre tetszőleges számú interfészt valósíthat meg, ezzel a polimorfizmus szempontjából a többszörös örökléshez hasonló eredményt érhetünk el Egy osztálynak kötelező implementálnia az általa megvalósított interfészek által definiált metódusokat (ellenkező eset fordítási hibát eredményez) Kivéve az absztrakt osztályokat, ahol nem szükséges minden metódust megvalósítani 7
Implicit/explicit interfész megvalósítás A többszörös öröklésnél felmerülő problémák közül néhány felmerül a több hasonló interfészt megvalósító osztályok esetén is Több interfész is tartalmazhat ugyanolyan szignatúrájú metódusokat, ennek kezelése érdekében kétféle interfész megvalósítást használhatunk Implicit megvalósítás az osztály metódusának a szignatúrája megegyezik az interfész(ek)ben megadott szignatúrával bármelyik interfésszel hivatkozunk az osztályra, mindig ugyanaz a metódus fut le Explicit megvalósítás: az osztályban a metódus neve mellett megadjuk az általa megvalósított interfész nevét is attól függően, hogy melyik interfésszel hivatkozunk az osztályra, mindig a megfelelő metódus fut le célszerű ezt a megvalósítást használni 8
Interfész típusú referencia Az interfészek tulajdonképpen típusok, ezért lehetséges ilyen típusú változók deklarációjára is Egy T típusú osztályra az alábbi típusú referenciákkal hivatkozhatunk (más típus fordítási hibát eredményez): T típusú referenciával T valamelyik őstípusának referenciájával T osztály által megvalósított valamelyik interfész típusának referenciájával (egyéb: konverziók, casting stb.) Az interfész típusú referenciák az osztály típusú referenciákhoz hasonló módon működnek Ez nem keverendő össze azzal, hogy az interfész típusból nem lehet példányt létrehozni! 9
Témakörök Polimorfizmus áttekintése Interfészek Interfészek kiterjesztése Eseménykezelési módszerek 10
Interfész hierarchia Az osztályokhoz hasonlóan az interfészek között is fel lehet építeni egy öröklődési hierarchiát (öröklődés helyett itt gyakran a kiterjesztés szót használjuk) Az osztályok és az interfészek hierarchiája egymástól független, interfész őse nem lehet osztály és osztály őse sem lehet interfész (az osztályok közti öröklést és az interfész megvalósítását tekintsük különbözőnek) Az osztályokhoz hasonlóan az interfészek is általában mind egy legmagasabb szintűősből származnak Az osztályokhoz hasonlóan a polimorfizmus előnyeit az interfészek között is alkalmazhatjuk (minden interfész használható bármelyik őse helyén) 11
Osztály hierarchia Amennyiben egy osztály megvalósít egy interfészt, akkor a leszármazottjai is mind megvalósítják. Ennek direkt jelölésére általában nincs szükség A megvalósító metódusokat a leszármazottak öröklik, így értelemszerűen nincs szükség további követelmények teljesítésére Egy T típusú osztályra tehát az alábbi típusú referenciákkal hivatkozhatunk: T típusú referenciával T valamelyik őstípusának referenciájával T osztály által megvalósított valamelyik interfész típusának referenciájával T osztály bármelyik őse által megvalósított interfész típusának referenciájával T osztály által megvalósított interfész bármelyik őstípusának referenciájával (egyéb: konverziók, casting stb.) 12
Néhány további gondolat Jelölő interfészek (marker interface) nincsenek metódusaik az osztályhoz rendelve futás közben lekérdezhetők, ezzel a futtató környezet (vagy reflexión keresztül az egyéb programok) számára nyújt információt ha van helyette más nyelvi elem, célszerű elkerülni a használatát Segítő osztályok (helper class) egy összetett interfész esetén gyakran csak néhány metódus megvalósítására lenne szükség, azonban mindig kötelező mindet implementálni kényelmi szempontból az interfészekhez gyakran készítenek egyszerű, az interfészt üres (vagy alapértelmezett kóddal) megvalósító ún. segítő osztályokat Nem célszerű interfészt új metódusokkal bővíteni, mivel így az ezt implementáló osztályok fordíthatatlanná válnak 13
Témakörök Polimorfizmus áttekintése Interfészek Interfészek kiterjesztése Eseménykezelési módszerek 14
Függvénymutatók A napjainkban használt (Neumann-elvű) architektúrák esetén a programok kódja azonos memóriában (és azonos módon) tárolódik az adatokkal Ez alapján technikailag egyszerűen megoldható, hogy egy mutató ne egy változóra, hanem egy függvény belépési címére mutasson Hagyományos nyelveknél ezzel lehetett megoldani a visszahívásokat (callback) Előnyei hatékony (gyors) Hátrányai bonyolult a : 8 bites szám Függvény Növel(k) k k + 1 Növel k Függvény vége nincs ellenőrzés (fordítás, futtatás közben) nagy a hibalehetőség (hibás kód, rosszindulatú kód stb.) 01011011101100110010101 01010101010101010001010 11010111010110101101010 00110101000111001010111 01000011100010101111000 11010100101011111100001 01101110110011001010101 01010101010101000101011 01011101011010110101000 11010100011100101011101 00001110001010111100011 01010010101111110000101 10111011001100101010101 01010101010100010101101 01110101101011010100011 01010001110010101110100 00111000101011110001101 01001010111111000010110 11101100110010101010101 01010101010001010110101 11010110101101010001101 01000111001010111010000 11100010101111000110101 00101011111100001011011 15
Eseménykezelés származtatással Az eseményeket küldő osztály rendelkezik olyan (alapesetben absztrakt vagy üres) metódusokkal, amelyeket az esemény bekövetkeztekor mindig meghív Az események kezeléséhez szükséges egy leszármazott osztály készítése, majd ott ezen metódusok implementálása A módszer többféleképpen megoldható minden eseményt egy metódus kezel minden eseményhez külön metódus tartozik Előnyei jól illeszkedik az OOP szemlélethez Hátrányai sok, gyakran minimális kóddal rendelkező osztály definiálását igényli az esemény forrása és az eseményhez tartozó kezelő nem függetlenek (pl. ugyanaz a kezelő több helyen?) Gomb +Lenyomás( ) +EseményKezelő( ) HelloGomb +EseményKezelő( ) 16
Eseménykezelés interfészekkel Az eseménykezelésben résztvevő típusok esemény támogató interfész eseményt küldő osztály (tárol egy vagy több, az interfészt megvalósító objektumreferenciát) eseményt kezelő osztály (megvalósítja ezt az interfészt) Eseménykezelés lépései eseménykezelő osztály definiálása eseménykezelő objektum példányosítása eseménykezelő objektum regisztrálása esemény bekövetkezte esetén a forrás az interfészen keresztül meghívhatja a kezelő metódusát Előnyei Gomb -kezelő(k) : IGombKezelő +Feliratkozás(IGombKezelő) +Leiratkozás(IGombKezelő) +Lenyomás( ) IGombKezelő <<interface>> IGombKezelő +LenyomásKezelő( ) GombKezelő +LenyomásKezelő( ) az esemény forrása és kezelője egymástól függetlenek 1 forrás N kezelő, N forrás 1 kezelő, N forrás N kezelő (általában az eseménykezelő metódus paramétere a forrás objektum) az interfész több metódust is tartalmazhat (lenyom, lenyit stb.) 17
Eseménykezelés metódusreferenciákkal Alapelve hasonló a függvénymutatóknál megismert módszerhez (legalábbis a programozó számára a metódusreferenciák kezelése hasonlónak tűnik) Lényeges különbségek csak objektumok metódusaira tudunk hivatkozni metódusreferencia értékadásánál szigorú típusellenőrzésen kell átesnie a metódusnak (paraméterek típusa, visszatérési érték) az eseménykezelés architektúrája megfelel az OOP alapelveinek Előnyei könnyen olvasható kód, nincs szükség új osztály definiálására (vagy interfészek megvalósítására) az események kezeléséhez példány és osztály metódusok egyaránt értékül adhatók eseménykezelés nyelvi szintű támogatásából eredő előnyök (pl. regisztráció, eseménykezelők tárolása stb.) Részletesebben: Vizuális Eseményvezérelt Programozás 18
Javasolt/felhasznált irodalom BMF NIK AAO, OOP, VEP előadások J. Richter: CLR via C# 2nd edition Microsoft press, 2006 Nyékyné Gaizler Judit: Java 2 útikalauz programozóknak 1.3, ELTE TTK Hallgatói alapítvány, Budapest 19