2009.03.09.
Öröklés és Polimorfizmus
Egy létező osztályból egy (vagy több) újat készítünk A létező osztályt ősnek, az újakat utódnak nevezzük Az utódok öröklik az ős minden tagját Az utódok az öröklött tagokat újakkal bővíthetik Az öröklés használata egyszerűbbé és átláthatóbbá teszi a programot
Öröklés fogalma
Specializáció: Az ősosztályt (álatlános) készítjük el először, ebből pedig az utódokat (speciális). Generalizáció: Az utódokat készítjük el először, majd ezekből a közös tagok kiemelésével az őst.
class Osztálydiagram
Jármű -
sebesség: int utasokszáma: int
+
Szállít() : void
Haj ó
Repülő
-
merülésimélység: int
-
szárnyfesztáv: int
+
Úszik() : void
+
Repül() : void
Öröklési szemléletmódok
1
2009.03.09.
Minden osztály egyszerre lehet ős és utód is Ebből egy osztályhierarchia alakul ki, amelyben az osztályok fát alkotnak A legtöbb OOP nyelvben az osztályhierarchia csúcsán az „Object” nevű osztály található
Osztályhierarchia
class UtódOsztályNév : ŐsOsztályNév { adattagok(ok) metódus(ok) }
Az utód örökli az ős összes adattagját, metódusát, tulajdonságát Az utódosztály deklarációjában csak azon tagok deklarációját kell elhelyezni, amelyek az ősben nem szerepelnek
Öröklés C#-ban
A konstruktor nem öröklődik Utódosztályból történő példánylétrehozáskor a konstruktorok meghívódása: ◦ Automatikus: az ősosztály alapértelmezett konstruktora hívódik ◦ Kézi: az ősosztály megfelelő paraméterekkel rendelkező konstruktora hívható
Konstruktorok és az öröklés
2
2009.03.09.
class A {
}
int adattag; public A(int adat) { adattag = adat; }
class B : A { public B(int ad) { adattag = adat; } } Hibás! Nincs az ősnek alapértelmezett konstruktora!
class A {
}
int adattag; public A(int adat) { adattag = adat; }
class B : A { public B(int ad) : base(ad) { } } Helyes!
Konstruktor meghívása C#-ban
Őstípusú referenciaváltozó hivatkozhat ős-, és utód típusú objektumra is Fordítva nem igaz Pl.:
Hajó aurora = new Hajo(); Repülő blackbird = new Repülő(); Jármű columbia = new Repülő(); Jármű titanic = new Hajó();
Polimorfizmus
Az őstől örökölt metódus elrejthető egy új változattal Az utódból készített objektumon keresztül az új változat érhető el Elrejtés szintaxisa az utódban: láthatóság new típus FüggvényNév(formális paraméterek) { függvénytörzs }
Az ősbeli és az utódbeli függvényeknek a szignatúrája (neve és paraméterei) meg kell, hogy egyezzen Az őstől örökölt változat meghívható a base kulcsszó használatával
Metódus elrejtése (hiding)
3
2009.03.09.
Mint az elrejtés, ez is az őstől örökölt függvény egy új változatának elkészítésére használatos Csak olyan függvény definiálható felül, amely az ősben virtuálisnak lett deklarálva Szintaxis az ősben: láthatóság virtual típus FüggvényNév(formális paraméterek) { függvénytörzs }
Szintaxis az utódban: láthatóság override típus FüggvényNév(formális paraméterek) { függvénytörzs }
Az ősbeli és az utódbeli függvényeknek a szignatúrája (neve és paraméterei) meg kell, hogy egyezzen Az őstől örökölt változat meghívható a base kulcsszó használatával
Függvény felüldefiniálása
Nemvirtuális függvények esetén a referenciaváltozó típusának megfelelő függvény hajtódik végre Virtuális függvények esetén a hivatkozott objektum típusának megfelelő függvény hajtódik végre
Virtuális vs. nem virtuális függvény
class A { }
public void MA(){ … } public virtual void MB(){ … }
class B : A { public new void MA(){ … } public override void MB(){ … } } class Program { static void Main(){ A aa = new A(); A ab = new B(); B bb = new B(); aa.MA(); aa.MB(); ab.MA(); ab.MB(); bb.MA(); bb.MB(); } }
Virtuális vs. nem virtuális példa
4
2009.03.09.
Nem virtuális metódus megfelelő változatának meghívása ős típusú referencián keresztül: ◦ Explicit típuskonverzióval: A ab = new B(); ((B)ab).MA();
◦ „as” operátorral: A ab = new B(); (ab as B).MA();
Virtuális vs. nem virtuális
Absztrakt metódusok Absztrakt osztályok
Az absztrakt metódusnak csak fejléce van, törzse nincs Deklarációjában a törzs helyett pontosvessző szerepel A metódus törzsét az osztály valamelyik utódjában kell megírni felüldefiniálással Az absztrakt metódust tartalmazó osztálynak absztraktnak kell lennie. Absztrakt osztályból nem lehet példányt létrehozni. láthatóság abstract típus FüggvényNév(formális paraméterek);
Absztrakt metódus
5
2009.03.09.
abstract class Síkidom { public abstract double Kerület(); public abstract double Terület(); } class Téglalap : Síkidom { double a, b; public Téglalap(double aa, double bb) { a = aa; b = bb; } public override double Kerület() { return 2 * (a + b);} public override double Terület() { return a*b; } } class Program { static void Main(){ Téglalap t1 = new Téglalap(10, 20); Console.WriteLine(t1.Kerület() + ”,” +t1.Terület()); } }
Absztrakt metódus
Statikus tagok
Az osztályhoz tartoznak Az osztályon keresztül lehet őket elérni Statikus adattag deklarációja:
láthatóság static típus adattagnév = kezdőérték;
Statikus metódus deklarációja: láthatóság static típus FüggvényNév(formális paraméterek) { függvénytörzs }
Statikus tagok elérése: OsztályNév.adattagnév OsztályNév.FüggvényNév(aktuális paraméterek)
Statikus (osztályszintű) tagok
6
2009.03.09.
db = 3
:Pöttöm Panna Név: Pöttöm Panna Neptunkód: AAA111
:Hüvelyk Matyi Név: Hüvelyk Matyi Neptunkód: BBB222
:Babszem Jankó Név: Babszem Jankó Neptunkód: CCC333
class Hallgató { static int db; string nev, neptunkod; public Hallgató(string n, string nk) { nev = n; neptunkod = n; ++db; } }
Statikus adattag
7