Ö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 Hajó - merülésimélység: int + Úszik() : void Jármű - sebesség: int - utasokszáma: int + Szállít() : void Repülő - szárnyfesztáv: int + Repül() : void Öröklési szemléletmódok 1
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
class A int adattag; public A(int adat) adattag = adat; 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 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
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
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
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
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