Programování v jazyce C++ Dědičnost a polymorfismus
OpakováníOpakování změny v C++ oproti C, změny v C++ oproti C, úvod do OOP, úvod do OOP, zapouzdření, zapouzdření, přístupová práva, přístupová práva, deklarace metod, deklarace metod, vznik a zánik objektu, vznik a zánik objektu, spřátelené funkce, spřátelené funkce,
Dědičnost inheritance, inheritance, mají-li některé třídy společné vlastnosti či metody, není třeba definovat každou třídu znovu, mají-li některé třídy společné vlastnosti či metody, není třeba definovat každou třídu znovu, jednotlivé vlastnosti či metody mohou třídy dědit, jednotlivé vlastnosti či metody mohou třídy dědit, na základě dědičnosti lze vytvářet hierarchie tříd, na základě dědičnosti lze vytvářet hierarchie tříd, třída vždy dědí od obecnější třídy. třída vždy dědí od obecnější třídy.
Příklad Sestavte hierarchii z těchto útvarů: Sestavte hierarchii z těchto útvarů: – Lichoběžník – Čtverec – Kosodélník – Obdélník – Kosočtverec
Terminologie následující výroky jsou ekvivalentní: následující výroky jsou ekvivalentní: – třída A dědí položky a metody třídy B, – třída A je potomkem (descendant) třídy B, – třída A podtřídou (subclass) třídy B, – třída A je odvozená (derived class) ze třídy B, – třída B je předkem (ancestor) třídy A, – třída B je nadtřídou (superclass) třídy A, – třída B je bázovou třídou (base class) třídy A.
Dědičnost v C++ v C++ je možno dědit od více předků, v C++ je možno dědit od více předků, nelze však přímo dědit dvojmo od jedné třídy, nelze však přímo dědit dvojmo od jedné třídy, předek musí být plně deklarován, předek musí být plně deklarován, dědí se metody a datové položky, dědí se metody a datové položky, nedědí se konstruktory, destruktor a přetížený operátor =, nedědí se konstruktory, destruktor a přetížený operátor =, při dědění lze měnit přístupová práva k datovým složkám i metodám. při dědění lze měnit přístupová práva k datovým složkám i metodám.
Deklarace odvozené třídy class A {…}; class A {…}; class B {…}; class B {…}; class C: A {…}; class C: A {…}; class C: private A {…}; class C: private A {…}; class C: A, B {…}; class C: A, B {…}; class C: public A, private B {…}; class C: public A, private B {…}; class C: public virtual B {…}; class C: public virtual B {…};
Nastavení přístupových práv private – všechny zděděné složky jsou v potomkovi specifikovány jako private, private – všechny zděděné složky jsou v potomkovi specifikovány jako private, protected – soukromé složky jsou nadále private, chráněné a veřejné jsou nastaveny jako protected, protected – soukromé složky jsou nadále private, chráněné a veřejné jsou nastaveny jako protected, public – přístupnost jednotlivých položek je stejná jako u předka, public – přístupnost jednotlivých položek je stejná jako u předka, implicitní je u tříd private. implicitní je u tříd private.
Konstruktory a destruktory konstruktory předků se volají před vstupem do těla konstruktoru potomka, konstruktory předků se volají před vstupem do těla konstruktoru potomka, je-li více předků, jejich konstruktory se volají v pořadí, v jakém byly napsány, je-li více předků, jejich konstruktory se volají v pořadí, v jakém byly napsány, destruktor předka je volán až po dokončení těla destruktoru potomka, destruktor předka je volán až po dokončení těla destruktoru potomka, je-li předkem odvozená třída, aplikují se tato pravidla rekurzivně. je-li předkem odvozená třída, aplikují se tato pravidla rekurzivně.
Konflikt jmen položek pokud se shodují názvy složek od různých předků případně název složky předka a potomka, lze je odlišit ::, pokud se shodují názvy složek od různých předků případně název složky předka a potomka, lze je odlišit ::, problém nastává např. při opakovaném dědění: problém nastává např. při opakovaném dědění: class A {int a}; class B:A {int b}; class C:A {int c}; class D:B, C {int d};
Virtuální dědění neexistenci dvou výskytů třídy A v třídě D lze zařídit pomocí virtuálního dědění, neexistenci dvou výskytů třídy A v třídě D lze zařídit pomocí virtuálního dědění, stačí předka A definovat ve třídách B a C jako virtuálního: stačí předka A definovat ve třídách B a C jako virtuálního: – class B: virtual A {int b}; je-li třída děděna virtuálně i nevirtuálně, pak je v potomkovi obsažena jednou za všechna virtuální dědění a jednou za každé nevirtuální, je-li třída děděna virtuálně i nevirtuálně, pak je v potomkovi obsažena jednou za všechna virtuální dědění a jednou za každé nevirtuální, v konstruktoru se volají nejprve konstruktory virtuálních předků. v konstruktoru se volají nejprve konstruktory virtuálních předků.
Polymorfismus v principu je instance dané třídy zastupitelná instancí třídy odvozené, v principu je instance dané třídy zastupitelná instancí třídy odvozené, všechny třídy odvozené od jednoho potomka mohou mít stejnou metodu: všechny třídy odvozené od jednoho potomka mohou mít stejnou metodu: – např. nakresli(), tato metoda však pro každý objekt udělá něco jiného, tato metoda však pro každý objekt udělá něco jiného, obecný předek nemusí mít metodu definovánu, pak ji označujeme jako abstraktní. obecný předek nemusí mít metodu definovánu, pak ji označujeme jako abstraktní.
Časná vs. pozdní vazba je-li do pointeru na předka přiřazen pointer na potomka, je volána metoda předka: je-li do pointeru na předka přiřazen pointer na potomka, je volána metoda předka: – toto je nazývá časná vazba, – volaná metoda je známá v době překladu, volanou metodu lze též určit až době běhu: volanou metodu lze též určit až době běhu: – jedná se o pozdní vazbu, – k tomu dochází u tzv. virtuálních metod, – tomuto mechanismu lze předejít, kvantifikujeme-li metodu názvem příslušné třídy.
Virtuální metody pro definici virtuálních metod se používá klíčové slovo virtual, pro definici virtuálních metod se používá klíčové slovo virtual, virtuální mohou být pouze objektové metody, virtuální mohou být pouze objektové metody, je-li metoda virtuální v dané třídě, bude virtuální i ve všech odvozených třídách, je-li metoda virtuální v dané třídě, bude virtuální i ve všech odvozených třídách, konstruktory, operátory delete a new a statické metody nelze definovat jako virtuální, konstruktory, operátory delete a new a statické metody nelze definovat jako virtuální, virtuální metody musí být deklarovány stejně: virtuální metody musí být deklarovány stejně: – musí mít stejné parametry a návratovou hodnotu.
Zastoupení předka potomkem je-li do instance předka přiřazen potomek, dochází k přetypování potomka na předka, je-li do instance předka přiřazen potomek, dochází k přetypování potomka na předka, přenesou se pouze složky existující v předkovi, přenesou se pouze složky existující v předkovi, k přetypování dochází pouze, je-li předek jednoznačný a nebrání-li v tom přístupová práva, k přetypování dochází pouze, je-li předek jednoznačný a nebrání-li v tom přístupová práva, operace přetypování předka na potomka je podstatně složitější. operace přetypování předka na potomka je podstatně složitější. pokud nastavíme referenci na předka na instanci potomka, ukazuje pouze na zděděný objekt. pokud nastavíme referenci na předka na instanci potomka, ukazuje pouze na zděděný objekt.
Předávání objektů funkci mějme třídu A, z ní odvozenou třídu B a funkci f(A a), která volá metodu objektu a, pak: mějme třídu A, z ní odvozenou třídu B a funkci f(A a), která volá metodu objektu a, pak: – při předání instance třídy B funkci f je vždy volána metoda třídy A, – při předání pointeru nebo reference na třídu B funkci f je volána metoda třídy B, je-li ve třídě A virtuální, opět je důležitá jednoznačnost a přístupnost předka v potomkovi. opět je důležitá jednoznačnost a přístupnost předka v potomkovi.
Abstraktní třídy slouží pro implementaci obecného předka dalších tříd, slouží pro implementaci obecného předka dalších tříd, některé metody takovéhoto předka nemá smysl definovat: některé metody takovéhoto předka nemá smysl definovat: – takováto metoda je označena jako virtuální a místo těla má řetězec "=0;", takováto metoda se nazývá čistě virtuální, takováto metoda se nazývá čistě virtuální, nesmí být vytvořena instance abstraktní třídy, nesmí být vytvořena instance abstraktní třídy, pointer nebo reference však ano. pointer nebo reference však ano.
Třídní ukazatele v C++ je možno získat adresu na libovolnou složku i metodu, v C++ je možno získat adresu na libovolnou složku i metodu, k tomu slouží třídní ukazatele, k tomu slouží třídní ukazatele, – int trida::*slozka; – int (trida::*metoda)(parametry); dereference je možná vzhledem ke konkrétní instanci, dereference je možná vzhledem ke konkrétní instanci, k přístupu ke složkám a metodám se pak používají operátory.* a ->*. k přístupu ke složkám a metodám se pak používají operátory.* a ->*.
Statické datové položky třídy je-li datová položka statická, pak je společná pro všechny instance třídy, je-li datová položka statická, pak je společná pro všechny instance třídy, existuje i před vznikem první a zánikem poslední instance, existuje i před vznikem první a zánikem poslední instance, mimo třídu je lze kvantifikovat názvem třídy nebo názvem libovolné instance, mimo třídu je lze kvantifikovat názvem třídy nebo názvem libovolné instance, – pro třídu používáme operátor ::, – pro instance operátor. nebo ->,
Statické metody mohou být volány bez odkazu na konkrétní instanci, mohou být volány bez odkazu na konkrétní instanci, možnost jejich použití opět není vázána na existenci instance, možnost jejich použití opět není vázána na existenci instance, obecně smí použít pouze statická data: obecně smí použít pouze statická data: – chci-li používat nestatická, musím danou instanci předat jako parametr, neexistuje v nich identifikátor this. neexistuje v nich identifikátor this.
DĚKUJI ZA POZORNOST A to je konec…
Použitá literatura Pavel Herout – Učebnice jazyka C, Pavel Herout – Učebnice jazyka C, Miroslav Virius – Od C k C++, Miroslav Virius – Od C k C++, Slajdy na předmět X36PJC z akademického roku 2008/2009 (Ladislav Vágner, Karel Müller), FEL ČVUT, Slajdy na předmět X36PJC z akademického roku 2008/2009 (Ladislav Vágner, Karel Müller), FEL ČVUT, Slajdy na předmět 36PJC z akademického roku 2004/2005 (Petr Matyáš), FEL ČVUT, Slajdy na předmět 36PJC z akademického roku 2004/2005 (Petr Matyáš), FEL ČVUT, Server Server