Programozási Paradigmák és Technikák Öröklődés Interfészek Kivételkezelés Rekurzió Eseménykezelés
© Szénási Sándor, Óbudai Egyetem, 2011
[email protected]
Programozási Paradigmák és Technikák Öröklődés Öröklődés a C# nyelvben Öröklődés feladatok Gyakorló feladatok
Interfészek Interfész a C# nyelvben Interfész feladatok
Kivételkezelés Saját kivételek készítése
Rekurzió Egyszerű rekurzív feladatok Visszalépéses keresés
Eseménykezelés Eseménykezelés interfészekkel Eseménykezelés delegáltakkal
Generikus típusok © Szénási Sándor, Óbudai Egyetem, 2011
[email protected]
Öröklődés a C# nyelvben • Leszármazott osztályok deklarációjánál „:” karakterrel elválasztva lehet megadni az ősosztály nevét (csak egyszeres öröklődés van) • Ezt követően csak az új mezőket/metódusokat kell felsorolni class Állat { int életkor; public Állat( ) { ... } public void Eszik( ) { ... } }
Állat életkor : Szám Állat() Eszik()
class Emlős : Állat { public Emlős Szül( ) { ... } }
Emlős Szül() : Emlős
class Macska : Emlős { string név; public void Nyávog( ) { ... } }
V 1.0
Macska név : Szöveg Nyávog() © Szénási Sándor, Óbudai Egyetem, 2011
[email protected]
3
Konstruktorok öröklődése • A konstruktorok nem öröklődnek – Van lehetőség meghívni az ősosztály konstruktorát a „base” kulcsszó segítségével (több ős konstruktor esetén a paraméterlista alapján dönt)
• Kötelező konstruktorhívás – A leszármazottban kötelező meghívni az ős valamelyik konstruktorát – Amennyiben nincs ilyen hívás, akkor az ős paraméter nélküli konstruktora automatikusan meghívódik (ha az ősnek nincs paraméter nélküli konstruktora, a fordító hibát jelez) class A { public A( ) { ... } }
V 1.0
class B : A { public B( ) { ... } }
class E : C { public E(int y) : base (y) { ... } }
class C : A { public C(int x) { ... } }
class F : C { public F( ) : base (5) { ... } }
© Szénási Sándor, Óbudai Egyetem, 2011
[email protected]
4
Virtuális és nemvirtuális metódusok • Nemvirtuális metódusok – Korai kötés jellemzi őket – Alapértelmezetten minden metódus nemvirtuális
• Virtuális metódusok – Késői kötés jellemzi őket – Külön szintaktikai megjelölést igényelnek • A virtuális metódusokat az ősosztályban a „virtual” kulcsszóval kell megjelölni • A leszármazottakban a felülbírált virtuális metódusokat az „override” kulcsszóval kell megjelölni (egyébként metódus elrejtés történik, lásd következő dia) • Az ős metódus elérhető a „base” kulcsszó segítségével class A { public virtual int Metodus( ) { ... } } class B : A { public override int Metodus( ) { ... } } V 1.0
© Szénási Sándor, Óbudai Egyetem, 2011
[email protected]
5
Metódusok elrejtése • Elrejtés: leszármazott osztályban azonos néven létrehozunk egy másik metódust – A leszármazott osztályban az új metódust a „new” kulcsszóval célszerű megjelölni (bár nem kötelező, a fordító figyelmeztet ha elmarad) – Az ősosztály azonos nevű metódusa elérhető a „base” kulcsszó segítségével
• Elrejtés - virtualitás – Mind virtuális, mind pedig nemvirtuális metódusok esetében használható (virtuális metódus esetén egy új virtuális hívási láncot indít) – Az elrejtésnek nincs köze a virtualitáshoz, valójában egymástól független metódusokat jelent, akiknek „véletlenül” azonos a nevük class A { public int MetodusX( ) { ... } public virtual int MetodusY( ) { ... } }
V 1.0
class B : A { public new int MetodusX( ) { ... } public new virtual int MetodusY( ) { ... } }
© Szénási Sándor, Óbudai Egyetem, 2011
[email protected]
6
Típuskényszerítés („casting”) • Típuskényszerítéssel egy objektumot úgy kezelhetünk, mintha egy másik típusú lenne – Implicit: automatikus típusátalakítás • Pl. számok közötti automatikus konverzió (egész → lebegőpontos), nincs szükség jelölésre
– Explicit: átalakítás a programozó kérésére • Jelölése: az átalakítandó típus elé zárójelbe írjuk a kívánt típust • Pl. Állat x; Macska y = (Macska)x; ((Macska)x).Nyávog();
• „is” operátor – Használata: „x is Állat” – Igaz értékkel tér vissza, ha az ellenőrizendő objektum a megadott osztályhoz, vagy annak valamely leszármazottjához tartozik
• „as” operátor – Használata: „x as Állat” – Ha az átalakítás sikerül, a kifejezés használható a megadott típusúként, egyébként a kifejezés értéke null lesz V 1.0
© Szénási Sándor, Óbudai Egyetem, 2011
[email protected]
7
Absztrakt osztály és metódus • Az absztrakt metódusokat és osztályokat az „abstract” kulcsszóval kell megjelölni – Egy osztály kötelezően absztrakt, ha legalább egy absztrakt metódusa van – Absztrakt osztályból nem lehet példányosítani – Absztrakt metódusokat a leszármazottban kötelező implementálni (vagy absztraktként jelölni) abstract class Síkidom { public abstract double Terület( ); public abstract double Kerület( ); } class Téglalap : Síkidom { int a; int b; public override double Terület( ) { return a * b; } public override double Kerület( ) { return 2 * (a * b); } } V 1.0
© Szénási Sándor, Óbudai Egyetem, 2011
[email protected]
8
Lezárt osztály és metódus • A lezárt metódusokat és osztályokat a „sealed” kulcsszóval kell megjelölni • Megjelölhető vele egyetlen metódus vagy egy teljes osztály is – Osztály esetén nem engedi a származtatást – Metódus esetén nem engedi a felülírást sealed class Téglalap : Síkidom { int a; int b; public override double Terület( ) { return a * b; } public override double Kerület( ) { return 2 * (a * b); } }
V 1.0
© Szénási Sándor, Óbudai Egyetem, 2011
[email protected]
9
Object ősosztály • Minden osztály közös őse a „System.Object” osztály • Amennyiben külön nem adunk meg egy osztálynak őst, akkor az automatikusan az Object leszármazottja lesz • Néhány fontosabb metódusa: – public Type GetType() Visszaadja a példány típusát reprezentáló objektumot – public virtual bool Equals(object obj) Egyenlőség vizsgálat, saját osztály esetén célszerű felülírni – public virtual int GetHashCode() Visszaad egy hash értéket, saját osztály esetén célszerű felülírni – public virtual string ToString() Tetszőleges szöveget ad vissza, a gyakorlatban gyakran jól használható – public static bool ReferenceEquals(object objA, object objB) Statikus metódus a referencia szerinti egyenlőségvizsgálathoz – public static bool Equals(object objA, object objB) Statikus metódus a tartalom szerinti egyenlőségvizsgálathoz V 1.0
© Szénási Sándor, Óbudai Egyetem, 2011
[email protected]
10
Programozási Paradigmák és Technikák Öröklődés Öröklődés a C# nyelvben Öröklődés feladatok Gyakorló feladatok
Interfészek Interfész a C# nyelvben Interfész feladatok
Kivételkezelés Saját kivételek készítése
Rekurzió Egyszerű rekurzív feladatok Visszalépéses keresés
Eseménykezelés Eseménykezelés interfészekkel Eseménykezelés delegáltakkal
Generikus típusok © Szénási Sándor, Óbudai Egyetem, 2011
[email protected]
Öröklődés példa • Feladat 1.1 Valósítsuk meg az oldalt látható osztályhierarchiát • Oldjuk meg az alábbiakat: – Tároljunk el 5 db síkidomot egy tömbben – Készítsünk egy metódust, ami egy síkidomot kilyukaszt, ha annak nagyobb a területe mint a kerülete – Készítsünk egy metódust, ami megadott oldalhosszak alapján létrehoz egy Téglalap vagy egy Négyzet objektumot – Készítsünk egy metódust, ami Síkidomok tömbjéből megadja a legnagyobb területű elemet V 1.0
© Szénási Sándor, Óbudai Egyetem, 2011
[email protected]
12
Öröklődés feladat (alap osztályok) • Feladat 1.2 - Készítsük el az alább felsorolt osztályokat • Tulajdonos osztály – Kívülről írható/olvasható formában tárolja el a tulajdonos nevét – Biztonsági okokból ne lehessen belőle származtatni
• BankiSzolgáltatás osztály – A konstruktorban lehessen megadni a tulajdonost, ez a későbbiekben csak olvasható legyen – Ebből az osztályból ne lehessen közvetlenül példányosítani
• Számla osztály – – – – – V 1.0
Legyen a BankiSzolgáltatás osztály leszármazottja Konstruktorában lehessen megadni a tulajdonost Kívülről csak olvasható formában tárolja el az aktuális egyenleget Egy Befizet(összeg) metódussal lehessen növelni az egyenleget Legyen egy hasonló paraméterű, de nem implementált Kivesz(összeg) metódusa is, aminek a visszatérési értéke egy logikai érték © Szénási Sándor, Óbudai Egyetem, 2011
[email protected]
13
Öröklődés feladat (számlák) • HitelSzámla osztály – Legyen a Számla osztály leszármazottja – A konstruktorban lehessen megadni a tulajdonos mellett a hitelkeret összegét, a későbbiekben ez csak olvasható legyen – Valósítsa meg úgy a Kivesz(összeg) metódust, hogy csak a hitelkeret mértékéig engedjen negatív számla egyenleget. Ellenkező esetben ne csökkentse az egyenleget és hamis visszatérési értékkel jelezze, hogy nem sikerült a kivétel
• MegtakarításiSzámla osztály – Legyen a Számla osztály leszármazottja – Kívülről írható/olvasható formában tárolja el a kamat mértékét – Az osztály egy statikus mezőjében tárolja el az alapértelmezett kamatot. Egy új megtakarítási számla létrehozásakor ez legyen a kamat kezdőértéke – A Kivesz(összeg) metódus ne engedje 0 alá csökkenni az egyenleget, visszatérési értéke jelezze, hogy sikerült-e a kivét – Legyen egy Kamatjóváírás() metódusa, ami jóváírja az esedékes kamatot V 1.0
© Szénási Sándor, Óbudai Egyetem, 2011
[email protected]
14
Öröklődés feladat (kártyák) • Kártya osztály – Legyen a BankiSzolgáltatás osztály leszármazottja – A konstruktorban lehessen megadni a tulajdonos mellett a hozzá tartozó mögöttes számlát, illetve a kártya számát – A kártyaszám legyen kívülről olvasható, a mögöttes számla nem módosítható – Készítsen egy Vásárlás(összeg) metódust, ami a paraméterként megadott összeggel megpróbálja csökkenteni a mögöttes számla egyenlegét, és visszatérési értéke legyen ennek sikeressége
• Számla osztály kiegészítése – Egészítse ki a Számla osztály egy ÚjKártya(kártyaszám) metódussal, amely a leendő kártyaszámot várja paraméterként – A metódus hozzon létre egy új kártyát (az aktuális számlát és annak tulajdonosát adva meg a kártya adataiként) és legyen ez a metódus visszatérési értéke
V 1.0
© Szénási Sándor, Óbudai Egyetem, 2011
[email protected]
15
Öröklődés feladat (bank) • Bank osztály – Tároljon el tetszőleges számú számlát, ezek maximális számát a Bank konstruktorában lehessen megadni – Legyen egy Számlanyitás(tulajdonos, hitelkeret) metódusa, amelynek paraméterei egy Tulajdonos objektum és egy hitelkeret összeg. A hitelkeret összegének megfelelően hozzon létre hitel vagy megtakarítási számlát, ezt tárolja el, és ez legyen a metódus visszatérési értéke is – Legyen egy Összegyenleg(Tulajdonos) metódusa, amely visszaadja a paraméterként átadott tulajdonos számláinak összegyenlegét – Legyen egy LegnagyobbEgyenlegűSzámla(Tulajdonos) metódusa, amely visszaadja a megadott tulajdonos legnagyobb egyenlegű számláját – Legyen egy Összhitelkeret() metódusa, amely visszaadja a bank által az összes ügyfélnek adott hitelkeretek összegét
• A fenti osztályok implementálását követően hozzon létre példa Tulajdonos és Bank objektumokat, majd próbálja ki a fenti funkciók működését V 1.0
© Szénási Sándor, Óbudai Egyetem, 2011
[email protected]
16
Programozási Paradigmák és Technikák Öröklődés Öröklődés a C# nyelvben Öröklődés feladatok Gyakorló feladatok
Interfészek Interfész a C# nyelvben Interfész feladatok
Kivételkezelés Saját kivételek készítése
Rekurzió Egyszerű rekurzív feladatok Visszalépéses keresés
Eseménykezelés Eseménykezelés interfészekkel Eseménykezelés delegáltakkal
Generikus típusok © Szénási Sándor, Óbudai Egyetem, 2011
[email protected]
Programozási tételek összeépítése (1) • Feladat 1.3 - mintaadatok Állatkertünkben háromféle állat tárolunk különböző méretű ketrecekben az alábbi mintaadatok szerint: Kormos
Morgó
Hím 20 kg
Hím 310 kg Mici Hím 320 kg Kajás
Hím 40 kg Killer Hím 3 kg
Nóri Hím 40 kg
Marcsi Nőstény 320 kg
Nőstény 13 kg
1. ketrec
Norbi Hím 5 kg
Karesz Hím 15 kg
2. ketrec
Kicsi Nőstény 10 kg
Kati
Nándi Hím 4 kg
Nyami Nőstény 12 kg
Kolbász
Hím 4 kg
Kaller Hím 5 kg
V 1.0
Hím 2 kg Morcos
Nőstény 320 kg
Nindzsa
Krumpli Hím 10 kg
3. ketrec
© Szénási Sándor, Óbudai Egyetem, 2011
[email protected]
4. ketrec
18
Programozási tételek összeépítése (2) • Feladat 1.3 - kérdések Válaszoljuk meg az alábbi kérdéseket az előző oldalon látható mintaadatokból felépített modell alapján. Az összetett feladatok során próbáljuk a már megismert programozási tételek (illetve az előzőleg elkészült részfeladatok) segítségével elkészíteni a megoldást. Tételek összeépítésénél használható mindhárom előadáson megismert összeépítési technika.
• Egyszerű programozási tételek (N → 1) – Megadott ketrecben hány darab megadott fajú állat található? int FajDarab(Allat[ ] A, AllatFaj faj) – Megadott ketrecben van-e megadott fajú és nemű állat? bool FajEsNemVanE(Allat[ ] A, AllatFaj faj, bool himnemu)
• Egyszerű programozási tételek (N → N) – Megadott ketrecben melyek a megadott fajú állatok? Allat[ ] FajAllatok(Allat[ ] A, AllatFaj faj)
V 1.0
© Szénási Sándor, Óbudai Egyetem, 2011
[email protected]
19
Programozási tételek összeépítése (3) • Programozási tételek összeépítése – Megadott ketrecben mennyi a megadott fajú állatok átlagos tömege? float AtlagFajTomeg(Allat[ ] A, AllatFaj faj) – Megadott ketrecben melyik a legnehezebb megadott fajú állat? Allat FajLegnehezebb(Allat[ ] A, AllatFaj faj) – Megadott ketrecben hány (a ketrecen belül a saját fajára számított) átlagosnál nehezebb állat van? int AtlagnalNehezebbDarab(Allat[ ] A) – Melyik ketrecben van a legtöbb (a ketrecen belül a saját fajára számított) átlagosnál nehezebb állat? int LegtobbAtlagnalNehezebb(Allat[ ][ ] A) – Hány olyan ketrec van, ahol az előzőleg kiszámolt számú átlagosnál nehezebb állat található? int LegtobbAtlagnalNehezebbDarab(Allat[ ][ ] A)
V 1.0
© Szénási Sándor, Óbudai Egyetem, 2011
[email protected]
20
Programozási tételek összeépítése (4) • Programozási tételek összeépítése – Melyik ketrecben található a legtöbb megadott fajú állat? int LegtobbFaj(Allat[ ][ ] A, AllatFaj faj) – Megadott ketrecben van-e legalább egy azonos fajú, de ellenkező nemű egyedekből álló páros? bool AzonosFajEllenkezoNemVanE(Allat[ ] A) – Megadott ketrecben tartozik-e mindenkihez legalább egy azonos fajú, de ellenkező nemű állat? (ahhoz nem ragaszkodunk, hogy mindenkihez egy kizárólagos pár tartozzon) bool AzonosFajEllenkezoNemMindenkinek(Allat[ ] A) – Hány olyan ketrec van, ahol van legalább egy azonos fajú, de ellenkező nemű tagokból álló páros? int AzonosFajEllenkezoDarab(Allat[ ][ ] A) – Hányas számú ketrecekben nincs egy azonos fajú, de ellenkező nemű egyedből álló pár se? int[ ] AzonosFajEllenkezoNemNincs(Allat[ ][ ] A)
V 1.0
© Szénási Sándor, Óbudai Egyetem, 2011
[email protected]
21
Összetett feladatok megoldása (1) • Feladat 1.4 - mintaadatok Receptkönyv
Raktár
besamel
kijevi
rostélyos
rántott hús
Liszt 50 g
Rizs 100 g
Vaj 10 g
Vaj 10 g
Hús 100 g
Vaj 50 g
Tej 100 g
Hús 100 g
Hús 100 g
Liszt 10 g
Tej 50 g
Tej 200 g
Vaj 50 g
Liszt 10 g
Tojás 10 g
Tej 100 g
Vaj 10 g
Hagyma 10 g
Hagyma 30 g
Hús
V 1.0
tejberizs
Teri
Feri
szereti
szereti
szereti
Vaj
Vaj
Liszt
Liszt
Rizs
Hús
allergiás
Tojás
Vaj 300 g Liszt 300 g Rizs 300 g Hús 50 g
Vendégek
Mari
Tej 300 g
Összetett feladatok megoldása (2) • Feladat 1.4 - kérdések Válaszoljuk meg az alábbi kérdéseket az előző oldalon látható mintaadatokból felépített modell alapján (zárójelben megadott osztályban).
• Egyszerű segéd metódusok – Receptkönyv egy megadott nevű receptjének a kiválasztása (ReceptKonyv) Recept ReceptKivalasztas(string nev) – Recept tartalmaz megadott alapanyagot? (Recept) bool TartalmazAlapanyagot(Alapanyag alapanyag) – Mennyi egy recept hozzávalóinak összesített mennyisége? (Recept) public float ReceptOsszMennyiseg( ) – Hány recept nem tartalmaz egy megadott alapanyagot? (ReceptKonyv) int HanyReceptNemtartalmazAlapanyagot(Alapanyag alapanyag) – Melyik receptek tartalmaznak egy megadott alapanyagot? (ReceptKonyv) Recept[ ] AlapanyagotTartalmazoReceptek(Alapanyag alapanyag) – Megadott vendég allergiás-e egy megadott alapanyagra? (AllergiasVendeg) bool AllergiasRa(Alapanyag alapanyag) V 1.0
© Szénási Sándor, Óbudai Egyetem, 2011
[email protected]
23
Összetett feladatok megoldása (3) • Receptek hozzávalóival kapcsolatos kérdések – Recept hányféle egymástól különböző alapanyagot tartalmaz? (Recept) int KulonbozoAlapanyagokSzama( ) – Melyik a legbonyolultabb recept (amelyik a legtöbb különböző alapanyagot tartalmazza)? (ReceptKonyv) public Recept LegbonyolultabbRecept( ) – Az egyes hozzávalókból összesítve mennyire van szükség a recept elkészítéséhez? (Recept) public Hozzavalo[ ] HozzavalokOsszesitve( ) – Megadott hozzávalókból elkészíthető-e a recept? (Recept) bool MegvalosithatoHozzavalokbol(Hozzavalo[ ] raktar) – Hányféle receptet lehet elkészíteni megadott hozzávalókból? (ReceptKonyv) int HanyfeleReceptValosithatoMegHozzavalokbol(Hozzavalo[ ] raktar) – Melyik recepteket lehet elkészíteni megadott hozzávalókból? (ReceptKonyv) Recept[ ] MelyikReceptekValosithatokMegHozzavalokbol(Hozzavalo[ ] raktar)
V 1.0
© Szénási Sándor, Óbudai Egyetem, 2011
[email protected]
24
Összetett feladatok megoldása (4) • Vendégekkel kapcsolatos kérdések – Mennyire jónak értékel egy vendég egy receptet (az általa szeretett hozzávalók mennyiségének az összege)? (Vendeg) virtual float Ertekel(Recept recept) – Valósítsuk meg az értékelést az allergiás vendégek esetén is (ha allergiás bármelyik hozzávalóra, akkor 0, egyébként a szokásos! (AllergiasVendeg) override float Ertekel(Recept recept) – Megadott vendégnek melyik receptet ajánljuk? (ReceptKonyv) Recept SzemelyreszabottAjanlat(Vendeg vendeg) – Mennyire jó egy recept egy társaság számára (a megadott vendégek értékelésének átlaga)? (Recept) float MennyireSikeres(Vendeg[ ] vendegek) – Megadott társaság számára melyik a legsikeresebb recept? (ReceptKonyv) Recept LegsikeresebbRecept(Vendeg[ ] vendegek)
V 1.0
© Szénási Sándor, Óbudai Egyetem, 2011
[email protected]
25
Programozási tételek – házi feladat • Házi Feladat 1.1
– – – – – – – – – – –
V 1.0
Egy 364 napos tömbben tároljuk az egy év (52 hét) alatt mért napi átlaghőmérsékleteket. Ezek ismeretében válaszoljunk az alábbi kérdésekre: Hány napon érte el a hőmérséklet az éves maximum 90%-át? Melyik volt az év legmelegebb hete (maximális heti átlaghőmérséklet)? Hány olyan hét volt, amikor legalább egyszer fagyott? Hány olyan hét volt, amikor minden nap fagyott? Melyik napon volt a legnagyobb lehülés az előző naphoz képest? Hány olyan nap volt, amikor előző és következő nap fagyott, de aznap nem? Mikor volt a leghosszabb időszak, amikor folyamatosan esett a hőmérséklet? Hányszor volt az évben kánikula? (legalább 3 napig 35°C feletti hőmérséklet) Volt-e olyan min. 5 napos időszak, amely értékei megismétlődtek később? Milyen hosszú volt az a leghosszabb időszak, amikor egyszer se fagyott? Milyen hosszú volt az a leghosszabb időszak, amelyen belül egyszer se fagyott egymást követő 5 napon át? © Szénási Sándor, Óbudai Egyetem, 2011
[email protected]
26
Összetett feladatok megoldása – házi feladat • Házi Feladat 1.2 Tervezzük meg és implementáljuk egy egyszerű szerszámkölcsönző cég rendszerét, amely megvalósítja az alábbi funkciókat: – Tárolja az aktuális időpontot (az év hányadik napja), ami menüből léptethető – Tárolja a kölcsönözhető eszközök adatait (típus {porszívó, fúrógép, lángvágó}, állapot {0..1}, alapdíj mértéke 10 napra, késedelmi díj mértéke ezt követően naponta) – Tárolja a kölcsönző személyek adatait (név, aktuális kölcsönzési adatok – eszköz, kölcsönzés ideje {max. 5 db}, előjegyzési lista {max. 5 db}) – Kölcsönzéskor a megadott típus alapján automatikusan válasszuk ki a legjobb állapotú, legdrágább eszközt és rögzítsük a kölcsönzést. Legyen lehetőség listázni az összes kölcsönzést – Ha nincs elérhető eszköz, vegyünk fel előjegyzést a legkorábban lejáró eszközre. Legyen lehetőség listázni az összes előjegyzést – Legyen lehetőség visszaadni egy eszközt, a program számolja ki az alapdíj és a késedelmi díj alapján a fizetendő összeget (illetve csökkentse az eszköz állapotát nap/100-al). Ha volt előjegyzés az eszközre, akkor automatikusan kerüljön át az új személyhez. – Legyen lehetőség meghosszabbítani egy kölcsönzést, de csak akkor, ha arra az eszközre még nincs előjegyzés – Selejtezéskor töröljük az eszközt és helyettesítsük a rá vonatkozó előjegyzéseket egy hasonlóval – Listázzuk eszköztípusonként, hogy aktuális napon mennyi bevételt hoznak a cégnek Töltsük fel a rendszert adatokkal, és menüvezérelt módon legyen lehetőség elérni a fenti funkciókat! V 1.0
© Szénási Sándor, Óbudai Egyetem, 2011
[email protected]
27
Programozási Paradigmák és Technikák Öröklődés Öröklődés a C# nyelvben Öröklődés feladatok Gyakorló feladatok
Interfészek Interfész a C# nyelvben Interfész feladatok
Kivételkezelés Saját kivételek készítése
Rekurzió Egyszerű rekurzív feladatok Visszalépéses keresés
Eseménykezelés Eseménykezelés interfészekkel Eseménykezelés delegáltakkal
Generikus típusok © Szénási Sándor, Óbudai Egyetem, 2011
[email protected]
Interfész C# nyelvben • Interfész létrehozása az „interface” kulcsszóval lehetséges – Fel kell sorolni a kötelezővé teendő metódusokat, tulajdonságokat
• Az interfész implementálása az ősosztály megadásához hasonló – Ha meg van adva ősosztály, akkor vesző után következik az interfész – Egyszerre több interfész is megvalósítható
• Interfész típus nem példányosítható, de referenciaváltozó lehet interface IÜzenetFogadó { bool Elérhető { get; set; } void ÜzenetKüldés(string üzenet); }
<
> IÜzenetFogadó Elérhető : Logikai ÜzenetKüldés(Szöveg)
class ChatPartner : Személy, IÜzenetFogadó { public bool Elérhető { get {...} set {…} } public void ÜzenetKüldés(string üzenet) { ... } }
ChatPartner
IÜzenetFogadó
IÜzenetFogadó x = new ChatPartner(); V 1.0
© Szénási Sándor, Óbudai Egyetem, 2011 [email protected]
29
Absztrakt osztály és interfész • Absztrakt osztály is megvalósíthat interfészt – Ilyenkor a metódust nem szükséges implementálni, azonban kötelezően absztraktként kell megjelölni – Ugyanez igaz az interfészben szereplő tulajdonságokra interface IEladható { bool Ár { get; set; } void Elad( ); } abstract class Termék : IEladható { public abstract bool Ár { get; set; } public abstract void Elad( ); }
• Az absztrakt osztály leszármazottainak implementálniuk kell a metódusokat és tulajdonságokat V 1.0
© Szénási Sándor, Óbudai Egyetem, 2011 [email protected]
30
Interfészek kiterjesztése • Interfészek kiterjesztése formailag hasonló az osztályok származtatásához („:” jel után kell megadni az ősöket) – Egy interfész egyszerre több másik interfészt is kiterjeszthet – Egy interfészt megvalósító osztálynak implementálnia kell az interfész ősei által előírt követelményeket is (metódusok, tulajdonságok, események stb.) interface IEladható { bool Ár { get; set; } void Elad( ); } interface IAkciózható : IEladható { void Akció(double kedvezmény); } public class Termék : IAkciózható { public bool Ár { get; set; } public void Elad( ) { ... } public void Akció(double kedvezmény) { ... } } V 1.0
© Szénási Sándor, Óbudai Egyetem, 2011 [email protected]
31
Implicit interfész megvalósítás • Implicit interfész megvalósítás – Ha több megvalósított interfész is tartalmaz ugyanolyan metódus szignatúrát (+maga a megvalósító osztály is tartalmazhat ilyen metódust), akkor azok egy metódussal is megvalósíthatók – Ebben az esetben mindegy, hogy melyik referenciával hivatkozunk az objektumra, mindig ez a metódus fog lefutni interface IFileKezelő { void Töröl( ); } interface IKorrektúra { void Töröl( ); } public class SzövegFile : IFileKezelő, IKorrektúra { public void Töröl( ) { … } }
V 1.0
© Szénási Sándor, Óbudai Egyetem, 2011 [email protected]
32
Explicit interfész megvalósítás • Explicit interfész megvalósítás – Ha több megvalósított interfész is tartalmaz ugyanolyan metódus szignatúrát (+ maga a megvalósító osztály is tartalmazhat ilyen metódust), akkor azok különböző metódussal is megvalósíthatók – Ebben az esetben a hívást végző referencia típusától függ, hogy melyik metódus fut le interface IFileKezelő { void Töröl( ); } interface IKorrektúra { void Töröl( ); } public class SzövegFile : IFileKezelő, IKorrektúra { public void Töröl( ) { … } void IFileKezelő.Töröl( ) { … } void IKorrektúra.Töröl( ) { … } } V 1.0
© Szénási Sándor, Óbudai Egyetem, 2011 [email protected]
33
Programozási Paradigmák és Technikák Öröklődés Öröklődés a C# nyelvben Öröklődés feladatok Gyakorló feladatok
Interfészek Interfész a C# nyelvben Interfész feladatok
Kivételkezelés Saját kivételek készítése
Rekurzió Egyszerű rekurzív feladatok Visszalépéses keresés
Eseménykezelés Eseménykezelés interfészekkel Eseménykezelés delegáltakkal
Generikus típusok © Szénási Sándor, Óbudai Egyetem, 2011 [email protected]
Meglévő interfész megvalósítása • Feladat 2.1 Készítsen egy tetszőleges osztályt, amely megvalósítja az IComparable interfészt – A .NET osztálykönyvtár tartalmaz egy IComparable nevű interfészt, amelyet megvalósítva egy objektum össze tudja hasonlítani önmagát egy másikkal – Az interfész csak egyetlen metódust határoz meg: int CompareTo(Object obj) A leírás alapján ennek lehetséges visszatérési értékei: • kisebb mint 0 – a példány megelőzi a paraméterként átadottat a sorrendben • 0 – a példány és a paraméterként átadott azonos helyen szerepelnek a sorrendben • nagyobb mint 0 – a példány követi a paraméterként átadottat a sorrendben
• Próbálja ki az így megvalósított objektumokat, egy belőlük létrehozott tömböt adjon át a beépített rendező metódusnak – A .NET osztálykönyvtár rendelkezik egy Array.Sort(Array) statikus metódussal – Ez a metódus rendezi a paraméterként átadott IComparable interfészt megvalósító objektumokat V 1.0
© Szénási Sándor, Óbudai Egyetem, 2011 [email protected]
35
Saját interfészek használata, kiterjesztés • Feladat 2.2 Valósítsuk meg az alább látható interfész és osztály hierarchiát
V 1.0
© Szénási Sándor, Óbudai Egyetem, 2011 [email protected]
36
Interfész feladat (alap osztály és interfészek) • Feladat 2.3 - Készítsük el a felsorolt osztályokat és interfészeket • IEladható interfész – Tartalmaz egy csak olvasható Ár tulajdonságot
• IKarbantartandó interfész – Tartalmaz egy logikai értéket visszaadó KarbantartásSzükséges() metódust, amely majd visszaadja, hogy szükséges-e a megadott termék karbantartása – Tartalmaz egy szöveget visszaadó Karbantartás() metódust, aminek a visszatérési értéke lesz a karbantartási esemény leírása
• Termék oszály – Legyen egy kívülről írható/olvasható Név tulajdonsága, amihez az értéket a konstruktorban lehessen megadni – Valósítsa meg az IEladható interfészt – Mivel ezen a szinten még nem ismerjük az egyes leendő termékek árképzésének módját, így legyen a kötelezően megvalósítandó Ár tulajdonság absztrakt (ennek megfelelően az egész osztály is) V 1.0
© Szénási Sándor, Óbudai Egyetem, 2011 [email protected]
37
Interfész feladat (Termék leszármazottak) • Cipő osztály – Legyen a Termék osztály leszármazottja, termék névnek automatikusan „Cipő” szöveget adjon át az ős konstruktorának – Tartalmazzon egy méret mezőt, amit a konstruktorban lehet megadni – Valósítsa meg az Ár tulajdonság lekérdezését, egy cipő ára legyen a mérettől függő: ha a méret > 40 akkor 15000 egyébként pedig 14000
• Virág osztály – A Termék leszármazottja, névnek a konstruktorban kapott nevet adja tovább – Tárolja el a virág korát, ebből képezze a szükséges árat is: 1000 + kor * 2 – Valósítsa meg a IKarbantartandó interfészt is az alábbi módon: • KarbantartásSzükséges : minden harmadik hívásnál adjon vissza igazat (a híváskor növelhetjük a virág korát) • Karbantartás : visszatérési értéke legyen az „Öntözés” szöveg
• Hűtő osztály – Valósítsa meg az IKarbantartható interfészt: a KarbantartásSzükséges mindig igazat adjon vissza, a Karbantartás leírása legyen a „Tisztítás” szöveg V 1.0
© Szénási Sándor, Óbudai Egyetem, 2011 [email protected]
38
Interfész feladat (fő modulok) • EladóModul osztály – Tároljon el tetszőleges számú (a maximumot a konstruktorban lehessen megadni) IEladható interfészt megvalósító objektumot – Legyen egy ÚjTermékFelvétele(IEladható) metódusa, amelyik felvesz egy új eladható elemet a fenti tömbbe – Legyen egy Legolcsóbb() metódusa, amelyik visszaadja a legolcsóbb termék referenciáját
• KarbantartóModul osztály – Tároljon el tetszőleges számú (a maximumot a konstruktorban lehessen megadni) IKarbantartandó interfészt megvalósító objektumot – Legyen egy ÚjKarbantartandóFelvétele(IKarbantartandó) metódusa, amelyik felvesz egy új karbantartandó elemet a fenti tömbbe – Legyen egy MindenKarbantartás() nevű metódusa, amely végignézi az összes eltárolt karbantartandó elemet, lekérdezi, hogy azok igényelnek-e karbantartást, és ha igen, akkor meghívja azok Karbantartás() metódusát. Annak visszatérési értékét írja ki a képernyőre V 1.0
© Szénási Sándor, Óbudai Egyetem, 2011 [email protected]
39
Interfész feladat (kiterjesztés) • IVisszaváltható interfész – Legyen az IEladható interfész kiterjesztése – Tartalmazzon egy VisszaváltásiÉrtéke(elteltNapokSzáma) metódust, amely egy egész számot ad vissza
• VásárlásiUtalvány osztály – Valósítsa meg az IEladható és az IVisszaváltható interfészeket is, mindkét esetben 1000-et adjon vissza (ár és visszaváltási érték a napoktól függetlenül)
• Cipő osztály kiegészítése – Valósítsa meg a Cipő osztály is az IVisszaváltható interfészt – A visszaváltási értéket az ár és az eltelt napok száma alapján számoljuk (lineárisan csökkenjen). Ha még aznap visszaváltják, akkor legyen egyenlő az eredeti árral, 50 nap esetén már legyen 0
• A fenti osztályok és interfészek implementálását követően hozzon létre minta objektumokat, majd próbálja ki a fenti funkciók működését V 1.0
© Szénási Sándor, Óbudai Egyetem, 2011 [email protected]
40
Programozási Paradigmák és Technikák Öröklődés Öröklődés a C# nyelvben Öröklődés feladatok Gyakorló feladatok
Interfészek Interfész a C# nyelvben Interfész feladatok
Kivételkezelés Saját kivételek készítése
Rekurzió Egyszerű rekurzív feladatok Visszalépéses keresés
Eseménykezelés Eseménykezelés interfészekkel Eseménykezelés delegáltakkal
Generikus típusok © Szénási Sándor, Óbudai Egyetem, 2011 [email protected]
Többrétegű architektúrák • Háromrétegű architektúra
Megjelenítés réteg (VEP)
Üzleti logika réteg (OOP, PPT)
Adat (erőforrás) réteg (ADB)
• Jellemzői – Minden réteg egy jól definiálható feladatot lát el, közvetlenül az alatta lévő réteget felhasználva – Ha nincs is szükség az egyes rétegek fizikai függetlenségére (pl. külön alkalmazásszerver), akkor is célszerű laza kapcsolatot építeni a szintek között – Előnyei: • Kódújrafelhasználás, modularitás, team-munka egyszerűsödik, kód áttekinthetőbb • Egyszerűbb karbantartás, jó skálázhatóság V 1.0
© Szénási Sándor, Óbudai Egyetem, 2011 [email protected]
42
Saját kivételek készítése (1) • Feladat 3.1 Készítsük el egy egyszerű bank modelljét, ahol az ügyfelek számlái mellett lehetőség van csoportos beszedési megbízások kezelésére is
• Sor osztály –
–
–
– V 1.0
Készítsük egy egyszerű sor adatszerkezetet az alábbi metódusokkal: Legyen egy konstruktora, ahol paraméterként meg lehet adni az adatszerkezet méretét public Sor(int meret) Egy metódus segítségével lehessen új objektumot berakni a sorba (Object típust, vagy annak leszármazottait). Amennyiben a fix méretű tömbbe már nem fér el több új elem, dobjon egy SorMegteltKivetelt public void Betesz(object elem) Legyen lehetőség kivenni az elsőként berakott elemeket a sorból. Ha üres sornak hívják meg ezt a metódusát, dobjon egy SorUresKivetelt public Object Kivesz() Egy tulajdonság mutassa meg, hogy üres-e a sor public bool Ures
Saját kivételek készítése (2) • BankSzamla osztály Egy bankszámla objektum az alábbi adatokat tárolja: számla azonosítója, számlatulajdonos neve, aktuális egyenleg. Rendelkezzen a mezőket kiolvasó tulajdonságokkal, illetve az alábbi műveletekkel: – Egy metódus segítségével legyen lehetőség megadott összeggel megterhelni a számlát. Amennyiben az aktuális egyenleg ezt megengedi, akkor csökkentse annak értékét a paraméterként átadott összeggel, ellenkező esetben pedig dobjon egy SzamlanNincsFedezetKivetelt public void Terhel(int osszeg) – A SzamlanNincsFedezetKivetel objektum mindig tartalmazza, hogy melyik számlát nem sikerült megterhelni, illetve ki lehessen belőle olvasni a sikertelenül terhelni próbált összeget is public BankSzamla Szamla public int Terheles
• Beszedes osztály Készítsünk egy Beszedes nevű osztályt, ami tárolja egy beszedés adatait: szolgáltató neve (aki a terhelést indítja), ügyfél neve (akitől le akarják vonni a pénzt), terhelendő összeg (a szolgáltatás havi díja) V 1.0
Saját kivételek készítése (3) • Bank osztály Készítsük el a bankot modellező osztályt is, ami tetszőleges adatszerkezetekben tárolja az alábbi adatokat: • számlák: Szamla objektumok (a bank által vezetett számlák listája) • engedélyek: Megbízás objektumok (melyik ügyfél, melyik szolgáltatónak, milyen maximális összeggel adott automatikus beszedési lehetőséget) • beszedésiSor: Megbízásokat tartalmazó sor, amelyik tartalmazza a cégektől folyamatosan érkező terhelési kéréseket (a feldolgozás során olyan sorrendben kell majd őket feldolgozni, ahogyan érkeztek)
– Ügyfél nyithasson új számlát egy név és egy nyitóösszeg megadásával (számlaszám automatikusan generálódjon) public void UjSzamlaNyitas(string tulaj, int nyitoosszeg) – Ügyfél tudjon engedélyt adni automatikus megbízás teljesítésre az ehhez szükséges adatok meghatározásával public void UjMegbizas(string szolgaltato, string ugyfel, int maxOsszeg) – Szolgáltató jelezhessen egy új beszedési igényt public void BeszedesFelvetele(string szolgaltato, string ugyfel, int osszeg) V 1.0
Saját kivételek készítése (4) • Bank osztály – Egy metódus meghívásával legyen lehetőség a sorban időközben összegyűlt beszedések feldolgozására. A bank ellenőrizze minden beszedés esetén annak jogosságát (engedélyek listája), illetve próbálja meg az ügyfél számláját megterhelni a kívánt összeggel (amennyiben az fedezet hiány miatt kivételt dobna, automatikusan próbálkozzon egy másik számlájával) public void BeszedesiSorFeldolgozasa() – A fenti metódus dobjon kivételeket az alábbi esetekben: • Amennyiben nincs a beszedés adatainak megfelelő (szolgáltató-ügyféllegalább ekkora összeg) engedély az ügyféltől, akkor dobjon egy BeszedesNemEngedelyezettKivetelt, amely tartalmazza a problémát okozó beszedés objektumot • Abban az esetben, ha talált megfelelő engedélyt, de az ügyfélnek nincs számlája, vagy egyik számláján sincs elegendő fedezet, dobjon egy BeszedesNemTeljesithetoKivetelt, ami a beszedés objektum mellett tartalmazza a pontos okot is (nincs számla, nincs egyenleg)
V 1.0
Programozási Paradigmák és Technikák Öröklődés Öröklődés a C# nyelvben Öröklődés feladatok Gyakorló feladatok
Interfészek Interfész a C# nyelvben Interfész feladatok
Kivételkezelés Saját kivételek készítése
Rekurzió Egyszerű rekurzív feladatok Visszalépéses keresés
Eseménykezelés Eseménykezelés interfészekkel Eseménykezelés delegáltakkal
Generikus típusok © Szénási Sándor, Óbudai Egyetem, 2011 [email protected]
Programozási tételek rekurzív formája • Feladat 4.1 Valósítsuk meg rekurzívan (ciklus használata nélkül) az alábbi feladatokat:
• Programozási tételek – Mennyi egy N elemű A tömb elemeinek az összege? int Osszegzes(int[ ] A, int N) – Egy N elemű A tömbben van-e 15-el osztható szám? bool Eldontes(int[ ] A, int N) – Egy N elemű A tömbben hol van a(z egyik) maximális érték? int MaximumKivalasztas(int[ ] A, int N)
• Logaritmikus keresés – Valósítsuk meg a keresés rekurzív változatát az alábbi paraméterekkel: • • • •
A – az elemeket tartalmazó tömb keresett – a keresett elem értéke alsoindex – a még vizsgálandó terület első elemének indexe felsoindex – a még vizsgálandó terület utolsó elemének indexe
int LogaritmikusKereses(int[ ] A, int keresett, int alsoindex, int felsoindex) V 1.0
© Szénási Sándor, Óbudai Egyetem, 2011 [email protected]
48
Programozási Paradigmák és Technikák Öröklődés Öröklődés a C# nyelvben Öröklődés feladatok Gyakorló feladatok
Interfészek Interfész a C# nyelvben Interfész feladatok
Kivételkezelés Saját kivételek készítése
Rekurzió Egyszerű rekurzív feladatok Visszalépéses keresés
Eseménykezelés Eseménykezelés interfészekkel Eseménykezelés delegáltakkal
Generikus típusok © Szénási Sándor, Óbudai Egyetem, 2011 [email protected]
Programozási Paradigmák és Technikák Öröklődés Öröklődés a C# nyelvben Öröklődés feladatok Gyakorló feladatok
Interfészek Interfész a C# nyelvben Interfész feladatok
Kivételkezelés Saját kivételek készítése
Rekurzió Egyszerű rekurzív feladatok Visszalépéses keresés
Eseménykezelés Eseménykezelés interfészekkel Eseménykezelés delegáltakkal
Generikus típusok © Szénási Sándor, Óbudai Egyetem, 2011 [email protected]
Visszalépéses keresés (1) • Feladat 4.2 Készítsünk egy visszalépéses keresésen alapuló Sudoku megoldó programot, amely a tábla üres helyeit kitölti az alábbi szabályok szerint: • Minden üres helyre egy szám írható 1..9 között • Egy sorban, illetve egy oszlopban nem szerepelhet kétszer ugyanaz a szám • A teljes tábla 3x3-as blokkokra oszlik, egy blokkon belül nem szerepelhet kétszer ugyanaz a szám (a tábla mérete 9x9 tehát összesen 9 blokkot tartalmaz)
• Visszalépéses keresés használatához javasolt átalakítások – Kétdimenziós tábla adatainak átalakítása részfeladatok sorozatává – Fixen megadott számok és a kitöltendő üres helyek szétválogatása 1 3
2 5
2
4 2
4 3
V 1.0
3
1
8
1
1
8
Fix mezők:
(0,0) (0,2) (0,3) (1,0) …
Üres mezők: (0,1) (0,4) (1,2) (1,3) …
3 © Szénási Sándor, Óbudai Egyetem, 2011 [email protected]
51
Visszalépéses keresés (2) • Megvalósítandó függvények – ft(szint, szám) függvény Visszatérési értéke igaz, ha az előre fixen beírt számok egyike sem zárja ki, hogy a szintedik részeredményhez tartozó mezőbe beírjuk a szám értéket bool ft(int szint, int szam) – fk(szint, szám, k, kszám) függvény Visszatérési igaz, ha a k. részeredményként választott kszám érték nem zárja ki, hogy a szintedik részeredményhez tartozó mezőbe beírjuk a szám értéket fk(int szint, int szam, int k, int kszam) – BackTrack(szint, címszerint VAN, E) Az előadáson megismert visszalépéses keresés algoritmus implementációja void BackTrack(int szint, ref bool VAN, int[ ] E) – Rekurziót indító metódus A fenti metódusok célszerűen nem publikusak, ezért készítsünk egy egyszerű, az algoritmus működésének (és bemenő paramétereinek) ismeretét nem feltételező indító metódust public bool MegoldasKereses() V 1.0
© Szénási Sándor, Óbudai Egyetem, 2011 [email protected]
52
Visszalépéses keresés (3) • Már megvalósított segéd metódusok – A Pozicio osztály lenti metódusa segítségével egyszerűen eldönthető, hogy a paraméterként átadott két mező kizáró kapcsolatban áll-e egymással (nem tartalmazhatják ugyanazt a számot). Visszatérési értéke csak akkor igaz, ha a két mező egy sorban, egy oszlopban vagy egy blokkban van: static int Kizaroak(Pozicio p1, Pozicio p2) – A Sudoku osztály alábbi metódusai elvégzik a tábla szétbontását fix és kitöltendő mezők listájára, illetve az eredmény betöltését az eredeti táblába: void MezoSzetvalogatas( ) void MezoOsszefuzesMegoldassal(int[ ] E) – A Program osztály rendelkezik egy statikus metódussal, amely segítségével ki lehet listázni egy tábla tartalmát a képernyőre: static void TablaKirajzolas(int[ , ] tabla) – A Program osztály rendelkezik egyéb statikus metódusokkal, amelyek visszaadnak egy-egy Sudoku feladvány táblát (a 0. mintatábla csak tesztelési célokat szolgál, ugyanis nem a játék szabályainak megfelelő méretű): static int[ , ] MintaTablaFeltoltes_?( ) V 1.0
© Szénási Sándor, Óbudai Egyetem, 2011 [email protected]
53
Rekurzió – házi feladat • Házi Feladat 4.1 Valósítsuk meg az alábbi programozási tételeket rekurzív formában: – – – – – –
Sorozatszámítás tétel Eldöntés tétel Kiválasztás tétel Keresés tétel Megszámlálás tétel Maximumkiválasztás tétel
• Házi Feladat 4.2
– – – –
V 1.0
Különböző tárgyakat (Tárgy objektumok az alábbi tulajdonságokkal: Súly, Méret, Hasznosság) szeretnénk elhelyezni egy véges méretű hátizsákban (mérete: ZsákMéret). A magunkkal cipelni kívánt tárgyakat egy tömbben tároljuk el. Készítsünk egy visszalépéses keresésen alapuló algoritmust, ami választ ad az alábbi kérdésekre: Hányféle elhelyezésre van lehetőségünk? Hogyan tudjuk a lehető legtöbb tárgyat elhelyezni a zsákban? Hogyan tudjuk a lehető leghasznosabb tárgyakkal telepakolni a zsákot? Hogyan tudjuk a lehető legnagyobbnak tűnő, de mégis legkönnyebb zsákot összeállítani?
© Szénási Sándor, Óbudai Egyetem, 2011 [email protected]
54
Programozási Paradigmák és Technikák Öröklődés Öröklődés a C# nyelvben Öröklődés feladatok Gyakorló feladatok
Interfészek Interfész a C# nyelvben Interfész feladatok
Kivételkezelés Saját kivételek készítése
Rekurzió Egyszerű rekurzív feladatok Visszalépéses keresés
Eseménykezelés Eseménykezelés interfészekkel Eseménykezelés delegáltakkal
Generikus típusok © Szénási Sándor, Óbudai Egyetem, 2011 [email protected]
Eseménykezelés interfészekkel • Feladat 5.1 - Készítsük el a felsorolt osztályokat és interfészeket • IHívásFigyelő interfész az alábbi követelményekkel – BejövőhívásTörtént(Telefon küldő, String forrás_telefonszám) – KimenőhívásTörtént(Telefon küldő, String cél_telefonszám)
• Telefon oszály – Legyen egy telefonszám nevű mezője, amit a konstruktorban lehet beállítani – Legyen egy egyenleg nevű mezője, amit az EgyenlegFeltöltés(int összeg) metódus hívásával lehet növelni – Legyen egy hívásfigyelő nevű, IHívásFigyelő típusú mezője, ami a regisztrált eseménykezelőt tárolja. Egy FigyelőRegisztrál(IHívásFigyelő figyelő) metódussal tudjon egy objektum regisztrálni az eseményekre – Legyen egy HívásFogadás(Telefon forrás) metódusa, amely meghívja az eseménykezelő objektum (ha az létezik) BejövőHívásTörtént metódusát – Legyen egy HívásKezdeményezés(Telefon cél) metódus, amely meghívja az eseménykezelő KimenőHívásTörtént metódusát, és ha az egyenleg engedi, meghívja a cél HívásFogadás metódusát, majd csökkenti az egyenleget V 1.0
© Szénási Sándor, Óbudai Egyetem, 2011 [email protected]
56
Eseménykezelő megvalósítása • HívásNapló oszály – Valósítsa meg az IHívásFigyelő interfészt – Mindkét szükséges metódus írja ki a képernyőre a paraméterként kapott adatokat
• A fenti osztályok és interfészek implementálását követően hozzon létre minta objektumokat, majd próbálja ki a fenti funkciók működését – – – – –
V 1.0
Hozzon létre legalább két Telefon objektumot Hozzon létre egy HívásNapló objektumot Regisztrálja a HívásNaplót a két telefonnál eseménykezelőként Töltse fel valamelyik Telefon egyenlegét Indítson néhány hívást a telefonokról
© Szénási Sándor, Óbudai Egyetem, 2011 [email protected]
57
Programozási Paradigmák és Technikák Öröklődés Öröklődés a C# nyelvben Öröklődés feladatok Gyakorló feladatok
Interfészek Interfész a C# nyelvben Interfész feladatok
Kivételkezelés Saját kivételek készítése
Rekurzió Egyszerű rekurzív feladatok Visszalépéses keresés
Eseménykezelés Eseménykezelés interfészekkel Eseménykezelés delegáltakkal
Generikus típusok © Szénási Sándor, Óbudai Egyetem, 2011 [email protected]
A képviselő („delegate”) • A képviselő segítségével egy osztályhoz külső osztályok kapcsolódhatnak – Más néven „delegált” vagy „metódusreferencia” – Tetszőleges osztály kapcsolódhat a képviselőn keresztül egy másik osztályhoz, ennek feltétele az előírt formátum betartása – Ez a formátum az üzenetváltáshoz hívandó metódus szignatúrája
• A képviselő segítségével egy osztály metódusai külső osztályok metódusait ismeretlenül is meg tudják hívni – Üzenetküldési lehetőség külső osztályok részére – Visszahívási, értesítési funkció
• A képviselők a delegate kulcsszó segítségével saját névvel és az általuk képviselendő metódusok szignatúrájával deklarálhatók public delegate void EventHandler(object sender, EventArgs e); • Neve: EventHandler • Visszatérési érték típusa: void • Paraméterek típusai: object és EventArgs V 1.0
© Szénási Sándor, Óbudai Egyetem, 2011 [email protected]
59
Metódushívás képviselőkön keresztül • Egyszerű metódushívás lépései – Példányosítani kell a képviselő osztályt, ehhez a konstruktorának át kell adni a későbbiekben hívandó metódust (megfelelő szignatúrával) – Ezt követően a létrejött képviselő objektumon keresztül meg lehet hívni az előzőleg a konstruktornak átadott metódust delegate double Közvetítő(double szám); static class Műveletek { public static double Kétszerezés(double szám) { return szám + szám; } } class Program { static void Main() { Közvetítő teszt = new Közvetítő(Műveletek.Kétszerezés); System.Console.WriteLine(teszt(5)); } } V 1.0
© Szénási Sándor, Óbudai Egyetem, 2011 [email protected]
60
Több metódus felfűzése (multicast) • Egy képviselő egyszerre több metódust is „tartalmazhat” – A += operátor segítségével lehet hozzáadni új metódust – A -= operátor segítségével lehet elvenni egy metódust delegate void SzövegFeldolgozó(string szöveg); static class Műveletek { public static void KiírNagy(string s) { System.Console.WriteLine(s.ToUpper()); } public static void KiírKicsi(string s) { System.Console.WriteLine(s.ToLower()); } } class Program { static void Main() { SzövegFeldolgozó teszt = new SzövegFeldolgozó (Műveletek.KiírNagy); teszt += new SzövegFeldolgozó (Műveletek.KiírKicsi); teszt(”Teszt Üzenet”); } }
V 1.0
© Szénási Sándor, Óbudai Egyetem, 2011 [email protected]
61
Néhány tipikus használati eset • Képviselő változóként – Az adatokhoz hasonlóan eltárolhat valamilyen funkciót • Bármikor meghívható • Bármikor megváltoztatható
– Tömb esetén funkciók egy teljes listáját tárolhatja
• Képviselő paraméterként – Paraméterként várhat valamilyen funkciót • Rendezés esetén a rendezési szempontot (< operátor megvalósítása) • Visszahívási lehetőség (a függvény kap egy funkciót és azt hívja meg bizonyos feltételek teljesülése esetén)
• Képviselő visszatérési értékként – Visszatérési értékként visszaadhat valamilyen funkciót • A hívónak nem is kell ismernie a rendelkezésre álló funkciót körét, a paraméterek alapján a metódus dönthet, hogy melyiket célszerű használni
• Eseménykezelés megvalósítására
V 1.0
© Szénási Sándor, Óbudai Egyetem, 2011 [email protected]
62
Az esemény („event”) • Az esemény egy kifejezetten értesítési célú nyelvi elem – Valójában egy korlátozott, biztonságosabbá tett képviselő
• Az eseménykezelés általános menete – Szükséges képviselő típusok létrehozása – Az osztály közzéteszi az eseményeit – Az esemény iránt érdeklődő osztályok saját metódusaik átadásával feliratkoznak az eseményre • Értelemszerűen csak megfelelő szignatúrájú metódussal • Feliratkozás a +=, leiratkozás a -= operátorral történik
– Amikor a közzétevő osztályban kiváltódik az esemény, a képviselők segítségével értesíti a feliratkozott osztályokat
• Esemény közzététele – Az események speciális mezők, amelyeket az event kulcsszó jelöl, rendelkeznek saját névvel, illetve egy képviselő által megadott típussal public event EventHandler Esemény;
V 1.0
© Szénási Sándor, Óbudai Egyetem, 2011 [email protected]
63
Eseménykezelés mintaprogram public delegate void SzamValtozott(int szamErtek); class Szamolo { public event SzamValtozott figyelo; int szam; public int Szam { set { szam = value; if (figyelo != null) figyelo(szam); } } } class Program { static void Figyelo(int szam) { Console.WriteLine("Változás:" + szam); } static void Main(string[ ] args) { Szamolo teszt = new Szamolo( ); teszt.figyelo += Figyelo; teszt.Szam = 10; } } V 1.0
© Szénási Sándor, Óbudai Egyetem, 2011 [email protected]
64
Eseménykezelés képviselőkkel • Feladat 5.2 - Készítsük el az alábbi osztályokat és képviselőket • Készítsünk képviselőket az alábbi események fogadásához – BejövőHívásTörtént(Telefon küldő, String forrás_telefonszám) – KimenőHívásTörtént(Telefon küldő, String cél_telefonszám)
• Telefon oszály – Legyen egy telefonszám nevű mezője, amit a konstruktorban lehet beállítani – Legyen egy egyenleg nevű mezője, amit az EgyenlegFeltöltés(int összeg) metódus hívásával lehet növelni – Legyen egy BejövőHívásFigyelő nevű, BejövőHívásTörtént típusú eseménye – Legyen egy KimenőHívásFigyelő nevű, KimenőHívásTörtént típusú eseménye – Legyen egy HívásFogadás(Telefon forrás) metódusa, amely meghívja a BejövőHívásFigyelő eseményre feliratkozott metódus(oka)t (ha léteznek) – Legyen egy HívásKezdeményezés(Telefon cél) metódusa, amely meghívja a KimenőHívásFigyelő eseményre feliratkozott metódus(oka)t, és ha az egyenleg engedi, meghívja a cél HívásFogadás metódusát, majd csökkenti az egyenleget V 1.0
© Szénási Sándor, Óbudai Egyetem, 2011 [email protected]
65
Eseménykezelő megvalósítása • HívásNapló oszály – Legyen egy statikus KimenőHívásTörtént metódusa, amely paraméterként egy Telefont és egy telefonszámot vár, majd írja ki a képernyőre a kapott adatokat – Legyen egy statikus BejövőHívásTörtént metódusa, amely paraméterként egy Telefont és egy telefonszámot vár, majd írja ki a képernyőre a kapott adatokat
• A fenti osztályok implementálását követően hozzon létre minta objektumokat, majd próbálja ki a fenti funkciók működését – Hozzon létre legalább két Telefon objektumot – Hozzon létre egy HívásNapló objektumot – Regisztrálja a HívásNaplót a két telefonnál eseménykezelőként mindkét eseményre – Töltse fel valamelyik Telefon egyenlegét – Indítson néhány hívást a telefonokról
V 1.0
© Szénási Sándor, Óbudai Egyetem, 2011 [email protected]
66
Egyenleget figyelő esemény • IEgyenleggelRendelekezik interfész – Készítsen egy ilyen nevű interfészt, amely egy metódus megvalósítását írja elő: EgyenlegFeltöltés(int összeg) – A már meglévő Telefon osztály valósítsa meg ezt az interfészt
• Készítsünk képviselőt az alábbi események fogadásához – EgyenlegAlacsony(IEgyenleggelRendelkezik küldő, int szükséges)
• Telefon osztály kiegészítése – Legyen egy új EgyenlegAlacsonyFigyelő nevű, EgyenlegAlacsony típusú eseménye – Amennyiben a hívás kezdeményezésnél az egyenleg 5 egység alá csökkenne, akkor a fenti eseményen keresztül hívja meg az arra feliratkozott metódusokat, paraméterként átadva önmagát, illetve a minimális 5 egységhez szükséges összeget – Ezt célszerű még a híváshoz szükség egyenleg ellenőrzése előtt megtenni, mivel egy azonnali feltöltéssel a hívást végre lehet hajtani V 1.0
© Szénási Sándor, Óbudai Egyetem, 2011 [email protected]
67
Automata egyenlegfeltöltő megvalósítása • EgyenlegAutomataFeltöltő osztály – Legyen egy saját egyenleg mezője, ami a konstruktorban kap kezdőértéket – Valósítsa meg az EgyenlegFeltöltés interfészt – Ennek az osztálynak is legyen egy EgyenlegAlacsonyFigyelő nevű, EgyenlegAlacsony típusú eseménye (mivel az automata pénze is elfogyhat) – Legyen egy TelefonAutomatikusFeltöltés metódusa, aminek szignatúrája megfelel az EgyenlegAlacsony képviselő által meghatározottnak: • Meghívása esetén, amennyivel a paraméterként kapott szükséges összeg rendelkezésre áll, akkor automatikusan hívja meg a paraméterként kapott telefon EgyenlegFelöltés metódusát a kért összeggel • Amennyiben az összeg nem áll rendelkezésre, hívja meg a saját EgyenlegAlacsonyFigyelő eseményén keresztül az ott figyelő metódusokat, paraméterként átadva önmagát, illetve 100 egységet. Ezt követően próbálja feltölteni a telefont.
• Új osztályok és események kipróbálása – Hozzunk létre egy új EgyenlegAutomataFeltöltő objektumot és kössük a telefonokhoz, majd indítsunk a telefonokról hívásokat – Hozzunk létre egy új KártyaVásárlás statikus metódust, ami figyeli az automata feltöltő EgyenlegAlacsony eseményét és szükség esetén feltölti azt V 1.0
© Szénási Sándor, Óbudai Egyetem, 2011 [email protected]
68
Programozási Paradigmák és Technikák Öröklődés Öröklődés a C# nyelvben Öröklődés feladatok Gyakorló feladatok
Interfészek Interfész a C# nyelvben Interfész feladatok
Kivételkezelés Saját kivételek készítése
Rekurzió Egyszerű rekurzív feladatok Visszalépéses keresés
Eseménykezelés Eseménykezelés interfészekkel Eseménykezelés delegáltakkal
Generikus típusok © Szénási Sándor, Óbudai Egyetem, 2011 [email protected]
Képek forrásai • • • • • • • •
V 1.0
http://www.supercoloring.com/wp-content/thumbnail/2009_01/onion-4-coloring-page.gif http://www.kids-n-fun.com/coloringpages/ToonKleurPlaat.aspx?imageurl=eten/eten21.gif&TExt=Kids-nFun%20%7C%20Coloring%20pages:%20Butter%20&kleurplaten=56 http://dclips.fundraw.com/zobo500dir/milk_bw.jpg http://dir.coolclips.com/clipart/150/vgjm/tf05034/CoolClips_food0403.jpg http://www.supercoloring.com/wp-content/main/2009_01/rice-6-coloring-page.gif http://www.supercoloring.com/pages/big-piece-of-meat/ http://ngfl.northumberland.gov.uk/clipart/Food/images/onion_jpg.jpg http://fc06.deviantart.net/fs70/f/2010/052/f/8/Chara_Egg_Base_by_drakangel614.png
© Szénási Sándor, Óbudai Egyetem, 2011 [email protected]
72