1 / 34

Microsoft.NET környezet

Microsoft.NET környezet. Hernyák Zoltán Programozási Nyelvek II. Eszterházy Károly Főiskola Számítástudományi tsz. 1. Constructor. Az osztályok megírásánál szempont, hogy az osztály felelős saját maga helyes működéséért. Ennek érdekében …

adelie
Télécharger la présentation

Microsoft.NET környezet

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. Microsoft.NET környezet Hernyák Zoltán Programozási Nyelvek II. Eszterházy Károly Főiskola Számítástudományi tsz 1

  2. Constructor • Az osztályok megírásánál szempont, hogy az osztály • felelős saját maga helyes működéséért. Ennek • érdekében … • induláskor egy alap állapotba kell helyezze • magát, majd … • működés közben nem szabad engednie, hogy • hibás állapotban helyezhessék. • E miatt elrejti a kritikus mezőit a külvilág elől, és • a publikus metódusai pedig csak ellenőrzött módon • változtatják meg az objektum állapotát. 2

  3. Constructor A CONSTRUCTOR olyan speciális metódus, amelyet a példány létrehozásakor kell meghívni. Ezen metódus felelős azért, hogy az objektum-példányt alap helyzetbe álljon. Ha a programozó elfelejti meghívni a konstruktort példányosításkor, akkor a példány nincs alaphelyzet- ben, használata során futás közbeni hibák, hibás működés következhet be. ‘Tisztességes’ programozási nyelvben nem lehet megkerülni a konstruktor hívását a nyelv szabályai miatt. A C# egy ‘tisztességes’ programozási nyelv. 3

  4. Constructor • A C#-ban a CONSTRUCTOR: • kötött a neve (uaz, mint az osztály neve) • nincs visszatérési típusa • fő feladata az osztály alaphelyzetbe állítása végrehajtódik, mielőtt a példány példány szintű metódusait meghívni esélyünk lenne • végrehajtódik, mielőtt tetszőleges virtuális metódust meghívni esélyünk lenne 4

  5. Korai kötés működése • class TVerem • { • private int vm; • public double Pop() { ... } • public void Push() { ... } • } • public TVerem () • { • vm = 0; • } TVerem v = new TVerem(); Konstruktor hívása ! A példány számára memória foglalása ! 5

  6. Constructor • A példányosítás két lépésből áll: • memória foglalás a mezők számára • A konstruktor meghívása • Ezen két lépés nem szétválasztható! TVerem v = new TVerem(); v.Push (100 ); TVerem v; … v = new TVerem(); v.Push( 100 ); A konstruktor lefut mielőtt meghívhatnánk bármely példányszintű metódust! 6

  7. Constructor TVerem v; v.Push( 100 ); A fenti kód írása lehetséges, de hibás. Nem történt meg a példányosítás, mielőtt a metódust meghívtuk volna! Ezért nem a konstruktor a felelős! Az ilyen programozási hibákat a C# fordító egyébként is észreveszi, és hibát jelez: Use of unassigned variable v! Use of = ‘használata’ Unassigned variable = olyan változó, amely még nem kapott értéket. 7

  8. Constructor • A C#-ban a CONSTRUCTOR: • … „kötött a neve (uaz, mint az osztály neve)” … Azt gondolnánk, hogy 1 osztály -> 1 konstruktor. De nem! Az overloading-nak köszönhetően • tetszőleges sok constructor-t készíthetünk az • osztályokhoz… • csak mindegyiknek el kell térni egymástól a • paraméterezésben (más-más paraméterezéssel) 8

  9. Korai kötés működése • class TKor • { • private int X,Y; • public TKor() • { • X = 0; • Y = 0; • } • public TKor(int kezdoX, int kezdoY) • { • X = kezdoX; • Y = kezdoY; • } • ... • } TKor k1 = new TKor(); TKor k2 = new TKor(10,20); 9

  10. Korai kötés működése class TAudi { private int motorLE = 160; private double fogyaszta = 14.5; private int maxSebesseg = 240; public void Inditas() { ...} public void BalraFordul(int szog) {...} ... } TAudi a = new TAudi(); ? Ez is konstruktor-hívás! Ha nem írunk egy osztályhoz konstruktort, akkor egy alapértelmezett konstruktor generálódik az osztályhoz! 10

  11. Constructor A C alapú nyelvekben (C, C++, Java, C#, …) létezik a ‘kezdőértékadás’ fogalom. Ha a konstuktorban csak konstans kezdőértékeket akarnánk a mezőkhöz rendelni, akkor ehhez felesleges konstruktort írni. Ezt megtehetjük kezdőértékadás formájában is. Ez eléggé gyakori eset. Ezért konstruktort ténylegesen csak ‘ritkán’ írunk. Viszont a példányosítás során kötelező meghívni egy létező konstruktort! 11

  12. Constructor Ha nem írunk egy konstruktort sem: akkor a fordító- program generál 1 üres paraméterezésű, üres törzsű publikus konstruktort. Ha mi írunk legalább 1 db konstruktort, akkor viszont a fordítóprogram nem fog készíteni ilyet. • class TKor • { • private int X,Y; • public TKor(int kezdoX, int kezdoY) • { • X = kezdoX; • Y = kezdoY; • } TKor k = new TKor(); Ez hibás, nincs ilyen paraméterezésű konstruktor! 12

  13. Constructor A konstruktorok védelmi szintje általában public. Ha nem public, akkor ugyanis nem lehet meghívni őket! • class TKor • { • private int X,Y; • private TKor(int kezdoX, int kezdoY) • { • X = kezdoX; • Y = kezdoY; • } TKor k = new TKor(10,20); Ez hibás! Van ilyen paraméterezésű konstruktor, de ‘kívülről’ nem elérhető! 13

  14. Constructor Az alábbi példa más szempontból is érdekes: Ebből az osztályból fizikai képtelenség példányt készíteni! Mivel példányosításkor kötelező konstruktort hívni, de ezen osztály konstruktorát nem lehet meghívni kívülről, ezért itt bezárult a kör! • class TKor • { • private int X,Y; • private TKor(int kezdoX, int kezdoY) • { • X = kezdoX; • Y = kezdoY; • } TKor k = new TKor(10,20); 14

  15. Constructor Ez lehet cél is! Hogy megakadályozzuk a példányosítást. Ez főleg akkor jön elő, ha az osztályunknak ‘csak’ osztályszintű metódusai vannak (pl. Console, Math, …) • class Console • { • private Console() • { • } Console c = new Console(); Azért kell megírni a konstrukort kézzel, hogy a fordító ne hozzon létre helyettünk konstruktort, mert amit ő csinál, az public lenne! 15

  16. Constructor Más értelme is van a konstruktor elrejtésének: • class TSajat • { • private TSajat() • { • } • public static TSajat Letrehoz() • { • return new TSajat(); • } Itt szabad hívni private szintű metódusokat! TSajat s = new TSajat(); Ez nem megy! TSajat s = TSajat.Letrehoz(); De ez működik! 16

  17. Object Factory • public static TSajat Letrehoz() • { • return new TSajat(); • } Az ilyen jellegű megoldásokat objektum-gyárnak (object factory) nevezzük. Az ilyen metódusoknak osztály szintűnek (static) kell lenniük, hogy példányosítás nélkül is meghívható legyen! Az object factory különböző ellenőrzéseket végezhet el, mielőtt új példányt hoz létre, illetve meg is tagadhatja a példány létrehozását! Ilyet használunk, ha értesülni akarunk a példányosításról! 17

  18. Object Factory public static TSajat Letrehoz(string nev, string jelszo) { if ( JelszoStimmel(nev,jelsz) ) return new TSajat(); else return null; } TSajat s = TSajat.Letrehoz(”pisti”,”jelszo123”); if (s==null) { … nem jó a jelszóm … } else { … dolgozom a példánnyal … } 18

  19. Object Factory private static dbSzam = 0; public static TSajat Letrehoz() { if (dbSzam>=10) return null; else { dbSzam++; return new TSajat(); } } TSajat s = TSajat.Letrehoz(); if (s==null) { … túl sok létrehozott példány … } else { … dolgozom a példánnyal … } 19

  20. Constructor A konstruktorok minden más szempontból egyszerű metódusnak tekintendőek. Szabad belőlük másik metódust is meghívni! • class TKor • { • private int X=10,Y=10; • private int sugar = 10; • public TKor() • { • Kirajzol(); • } • public void Kirajzol() { ... } 20

  21. Constructor De mi a helyzet a virtuális metódusokkal? • class TAlapGrafikusOsztaly • { • public virtual Kirajzol() { ... } • } • class TKor:TAlapGrafikusOsztaly • { • private int X=10,Y=10; • private int sugar = 10; • public TKor() • { • Kirajzol(); • } • public override Kirajzol() { ... } ? 21

  22. Constructor A virtuális metódusok helyes kezeléséhez VMT tábla megléte szükséges. A VMT táblát a példány készítésekor a példányhoz kell hozzárendelni (csatolni). A VMT táblát éppen a konstruktor rendeli hozzá a példányhoz  • public TKor() • { • Kirajzol(); // ezért itt már működik is ! • } • public override Kirajzol() { ... } // itt történik meg a VMT hozzárendelés (automatikus) 22

  23. Constructor A konstruktor ha más semmit sem csinál, akkor is megtesz annyit, hogy a VMT táblát hozzárendeli a példányhoz. Ez a hozzárendelés a legtöbb nyelven a konstruktor kódjának futása előtt történik meg. Ezért a konstruktor belsejében már működik a késői kötés, és lehet hívni a virtuális metódusokat! • public TKor() • { • Kirajzol(); // ezért itt már működik is ! • } • public override Kirajzol() { ... } // itt történik meg a VMT hozzárendelés (automatikus) 23

  24. Constructor A konstruktor ha más semmit sem csinál, akkor is megtesz annyit, hogy a VMT táblát hozzárendeli a példányhoz. Ez a hozzárendelés a legtöbb nyelven a konstruktor kódjának futása előtt történik meg. Ezért a konstruktor belsejében már működik a késői kötés, és lehet hívni a virtuális metódusokat! • public TKor() • { • Kirajzol(); // ezért itt már működik is ! • } • public override Kirajzol() { ... } // itt történik meg a VMT hozzárendelés (automatikus) 24

  25. Constructor Konstruktorból meghívható egy másik konstruktor is, speciális módon ( ‘:’ és a konstruktor neve) • class TKor • { • private int X,Y; • public TKor():TKor(0,0) • { • // itt már más dolgunk nincs is • } • public Tkor(int ujX, int ujY) • { • X = ujX; • Y = ujY; • } • } TKor k1 = new TKor(30,40); TKor k2 = new TKor(); 25

  26. Constructor Konstruktorból meghívható az ős osztály konstruktora is, speciális módon ( ‘:’ és ‘base’ szó) • class TOs • { • public TOs(int akarmi) • { • } • } • class TGyerek:TOs • { • public TGyerek():base (10) • { • ... • } 26

  27. Constructor Ha az osztályunknak van őse, akkor mielőtt a mi konstuktorunk lefutna, előtte a rendszer lefuttatja automatikusan az összes ős osztályunkból legalább egy db konstruktort. Ha az ősnek van paraméter nélküli konstruktora, akkor azt a C# automatikusan kiválasztja és meghívja. Ha ilyen nincsen neki, akkor az ős konstruktort nekünk kell felparaméterezni, és meghívni a ‘base(…)’ hívással! 27

  28. Constructor E miatt ha az ősnek csak paraméteres konstruktora van, akkor a gyermek osztályban is kötelező konstuktor írni! class TOs { public TOs(int akarmi) { ... } } class TGyerek:TOs { // nem írunk konstruktort } Ekkor ugyanis (mivel mi nem írunk konstuktort) a fordítóprogram fog egy üres konstuktort generálni, de honnan adjon át paramétert az ősnek? 28

  29. Constructor Az előző megoldás ekvivalens ezzel: class TOs { public TOs(int akarmi) { ... } } class TGyerek:TOs { public TGyerek() { ... } } 29

  30. Constructor De az ős konstruktorát ilyenkor nekünk kell meghívni, és felparaméterezni! class TOs { public TOs(int akarmi) { ... } } class TGyerek:TOs { public TGyerek():base(0) { ... } } 30

  31. Constructor Gyakoribb, hogy amilyen paramétert az ős bekér, olyat mi is kérünk, és továbbadjuk az ősnek! class TOs { public TOs(int akarmi) { ... } } class TGyerek:TOs { public TGyerek(int akarmi):base(akarmi) { ... } } 31

  32. Constructor Ha egy osztálynak vannak osztályszintű metódusai, és osztályszintű mezői, akkor ezeket is alaphelyzetbe kell állítani! Erre nem jó az eddig tanult konstruktor, mert az a példányszintű alaphelyzetről gondoskodik csak, hiszen példányosításkor fog lefutni. Osztályszintű mezők eléréséhez, metódus hívásához pedig nem is kell példányosítani. Ezért létezik az osztályszintű konstruktor! 32

  33. Constructor class TSajat { static TSajat() { ... } } Osztályszintű konstruktor: - neve ugyanaz, mint az osztály neve - nem lehet paramétere ! - static módosítójú - kötelezően public (ezért nem is lehet neki semmilyen elérési szint módosítója) Osztályszintű konstruktorból még az overloading mellett sem lehet több, mint 1 db ! 33

  34. Constructor Az osztályszintű konstruktort kódból nem lehet meghívni (explicit módon)! Az osztályszintű konstruktort a futtató rendszer hívja meg automatikusan (ezért nem lehet neki paramétere), a program indulásának elején! 34

More Related