Interfészek
[email protected] 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 <
> IComperable +equals( ) +more( ) +less( )
interfész definíció
Number IComperable +equals( ) +more( ) +less( )
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 01011011101100110010101 • Hagyományos nyelveknél a : 8 bites szám 01010101010101010001010 11010111010110101101010 00110101000111001010111 ezzel lehetett megoldani a 01000011100010101111000 11010100101011111100001 visszahívásokat (callback) 01101110110011001010101 01010101010101000101011 01011101011010110101000 • Előnyei 11010100011100101011101 – hatékony (gyors)
• Hátrányai
Függvény Növel(k) k ← k + 1 Növel ← k Függvény vége
– bonyolult – nincs ellenőrzés (fordítás, futtatás közben) – nagy a hibalehetőség (hibás kód, rosszindulatú kód stb.)
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 Gomb • A módszer többféleképpen megoldható – minden eseményt egy metódus kezel – minden eseményhez külön metódus tartozik
+Lenyomás( ) +EseményKezelő( )
• Előnyei – jól illeszkedik az OOP szemlélethez
• Hátrányai
HelloGomb
– sok, gyakran minimális kóddal rendelkező +EseményKezelő( ) 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?) 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 – – – –
<> IGombKezelő +LenyomásKezelő( )
Gomb -kezelő(k) : IGombKezelő +Feliratkozás(IGombKezelő) +Leiratkozás(IGombKezelő) +Lenyomás( )
eseménykezelő osztály definiálása eseménykezelő objektum példányosítása eseménykezelő objektum „regisztrálása” GombKezelő esemény bekövetkezte esetén a forrás az interfészen keresztül IGombKezelő +LenyomásKezelő( ) meghívhatja a kezelő metódusát
• Előnyei – 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