Programozás II. 6.Öröklés Dr. Iványi Péter 1
Öröklés Programozók lusta emberek, nem szeretnék valamit kétszer leírni Miért veszélyes? Nem hatékony Újra kell tárolni a kódot, újra le kell fordítani Karbantartás nehéz Könnyű másolni, de a módosítást átvezetni minden helyre nehezebb 2
Öröklés Megírtunk egy osztályt és szükségünk van egy hasonlóra OOP megoldás az öröklés, kiterjesztés Eredeti kód változatlan marad, továbbfejleszthetjük Új kódban felhasználhatjuk a régit és felül is bírálhatjuk C++ öröklést használ, Java kiterjesztést 3
Öröklés Az öröklés után az új osztály az eredeti osztály minden tagváltozójával és tagfüggvényével rendelkezik Szintaxis: class öröklő-osztály : hozzáférés alap-osztály // az osztály definíció 4
Öröklés hozzáférés public hozzáférés azt jelenti hogy az öröklő osztályban az alap-osztály minden publikus eleme publikus lesz a private részekhez az öröklő osztályban sem lehet hozzáférni 5
#include <iostream> using namespace std; class alap int i, j; void set(int a, int b) i=a; j=b;} void show() cout << i << " " << j << endl; } class oroklo : public alap int k; oroklo(int x) k = x; } void showk() cout << k << endl; } 6
void main() oroklo ob(3); ob.set(1,2); // alap osztály beállítása ob.show(); } ob.showk(); // 3-at nyomtat 7
Öröklés hozzáférés privatehozzáférés azt jelenti hogy az öröklő osztályban az alap-osztály minden publikus eleme privatelesz 8
#include <iostream> using namespace std; class alap int i, j; void set(int a, int b) i=a; j=b;} void show() cout << i << " " << j << endl; } class oroklo : private alap int k; oroklo(int x) k = x; } void showk() cout << k << endl; } 9
void main() oroklo ob(3); ob.set(1,2); // HIBA: nem fordul le, priváttá vált!!! ob.show(); // HIBA: nem fordul le, priváttá vált!!! } 10
Öröklés hozzáférés Ha az alap osztály public módon öröklődik, akkor az alap osztály protected elemei az öröklő osztályban is protected-ek lesz, de elérhetőek!!! 11
#include <iostream> using namespace std; class alap protected: int i, j; void set(int a, int b) i=a; j=b;} void show() cout << i << " " << j << endl; } class oroklo : public alap int k; void setk() k=i*j; } void showk() cout << k << endl; } 12
void main() oroklo ob; ob.set(1,2); // OK ob.show(); // OK } ob.setk(); // OK ob.showk(); // OK 13
#include <iostream> using namespace std; Továbböröklés esetén class alap protected: int i, j; void set(int a, int b) i=a; j=b;} void show() cout << i << " " << j << endl; } class oroklo1 : public alap int k; void setk() k=i*j; } void showk() cout << k << endl; } 14
class oroklo2 : public oroklo1 int m; void setm() m=i-j; } void showm() cout << m << endl; } void main() oroklo1 ob1; oroklo2 ob2; ob1.set(2,3); ob1.show(); ob1.setk() ob1.showk() } ob2.set(4,5); ob2.setk(); ob2.setm(); ob2.showk(); ob2.showm(); // ez is OK // ez is OK // ez is OK // ez is OK 15
#include <iostream> using namespace std; Továbböröklés esetén class alap protected: int i, j; void set(int a, int b) i=a; j=b;} void show() cout << i << " " << j << endl; } class oroklo1 : private alap int k; void setk() k=i*j; } void showk() cout << k << endl; } i és j priváttá válik!!! de ez még jó 16
class oroklo2 : public oroklo1 int m; void setm() m=i-j; } void showm() cout << m << endl; } i és j privát, ez már nem legális 17
Öröklés hozzáférés Ha az alap osztály protected módon öröklődik, akkor az alap osztály minden publikus és protected eleme az öröklő osztályban is protected-ek lesz, vagyis elérhető 18
Öröklés több osztályból Több osztályból is lehet örökölni Az összes tulajdonság megjelenik az öröklőben, az előző szabályok alapján 19
#include <iostream> using namespace std; Többszörös öröklés esetén class alap1 protected: int x; void showx() cout << x << endl; } class alap2 protected: int y; void showy() cout << y << endl; } 20
class oroklo : public alap1, public alap2 void set(int i, int j) x=i; y=j; } void main() oroklo ob; } ob.set(1,2); ob.showx(); ob.showy(); 21
Öröklés és konstruktorok Mikor futnak le a konstruktorok? Alap és öröklő osztály konstruktorai és destruktorai Az öröklő osztály konstruktora először az alap osztály konstruktorát futtatja le Az öröklési sorrendben hívódnak meg Destruktorok esetén először az öröklő osztályé fut le, majd az alap osztály konstruktora Fordított sorrend 22
#include <iostream> using namespace std; class alap alap() cout << "Konstruktor alap" << endl; } ~alap() cout << "Destruktor alap" << endl; } class oroklo : public alap oroklo() cout << "Konstruktor oroklo" << endl; } ~oroklo() cout << "Destruktor oroklo" << endl; } 23
void main() oroklo ob; } // Konstruktor alap // Konstruktor oroklo // Destruktor oroklo // Destruktor alap 24
#include <iostream> using namespace std; Továbböröklés esetén class alap alap() cout << "Konstruktor alap" << endl; } ~alap() cout << "Destruktor alap" << endl; } class oroklo1 : public alap oroklo1() cout << "Konstruktor oroklo1" << endl; } ~oroklo1() cout << "Destruktor oroklo1" << endl; } 25
class oroklo2 : public oroklo1 oroklo2() cout << "Konstruktor oroklo2" << endl; } ~oroklo2() cout << "Destruktor oroklo2" << endl; } void main() oroklo2 ob; } // Konstruktor alap // Konstruktor oroklo1 // Konstruktor oroklo2 // Destruktor oroklo2 // Destruktor oroklo1 // Destruktor alap 26
#include <iostream> using namespace std; Többszörös öröklés esetén class alap1 alap1() cout << "Konstruktor alap1" << endl; } ~alap1() cout << "Destruktor alap1" << endl; } class alap2 alap2() cout << "Konstruktor alap2" << endl; } ~alap2() cout << "Destruktor alap2" << endl; } 27
class oroklo : public alap1, public alap2 oroklo() cout << "Konstruktor oroklo" << endl; } ~oroklo() cout << "Destruktor oroklo" << endl; } void main() oroklo ob; } // Konstruktor alap1 // Konstruktor alap2 // Konstruktor oroklo // Destruktor oroklo // Destruktor alap2 // Destruktor alap1 28
class oroklo : public alap2, public alap1 oroklo() cout << "Konstruktor oroklo" << endl; } ~oroklo() cout << "Destruktor oroklo" << endl; } Másik változat void main() oroklo ob; } // Konstruktor alap2 // Konstruktor alap1 // Konstruktor oroklo // Destruktor oroklo // Destruktor alap1 // Destruktor alap2 29
Öröklés és konstruktorok Ha az öröklő osztály konstruktorának kell argumentum, nincs gond, de Hogyan adhatunk át az alap osztály konstruktorának paramétert? Konstruktor inicializáló lista 30
#include <iostream> using namespace std; Öröklés és konstruktor argumentummal class alap protected: int i; alap(int x) i=x; cout << "Konstruktor alap" << endl; } ~alap() cout << "Destruktor alap" << endl; } class oroklo : public alap int j; oroklo(int a, int b) : alap(b) j=a; cout << "Konstruktor oroklo" << endl; } ~oroklo() cout << "Destruktor oroklo" << endl; } void show() cout << i << " " << j << endl; } 31
void main() oroklo ob(3, 4); ob.show(); // 4 3 } // Konstruktor alap // Konstruktor oroklo // Destruktor oroklo // Destruktor alap 32
Öröklés és jogok Ha private az öröklés, azért még lehetővé tehetjük, hogy az alap osztály publikus részeit elérhessük A privát öröklés alapból ezt nem engedi 33
#include <iostream> using namespace std; class alap int i; int j, k; void seti(int x) i=x; } int geti() return i; } 34
class oroklo : private alap alap::j; // tegyük j-t publikussá alap::seti; alap::geti; // alap::i; // ez eleve privát volt!!! void main() oroklo ob; // ob.i = 10; // illegális ob.j = 20; // ob.k = 30; // ez is illegális ob.seti(40); } 35
Öröklés és tagfüggvények Az öröklés során a tagfüggvényeket is felül lehet definiálni Figyeljünk arra, hogy ne rejtsük el az alap osztály tagfüggvényeit 36
#include <iostream> using namespace std; class emlos void mozog() cout << "Emlos mozog" << endl; } void mozog(int lepes) cout << "Emlos " << lepes << " lepest tesz" << endl; } protected: int kor; int suly; class kutya : public emlos void mozog() cout << "Kutya mozog" << endl; } 37
void main() emlos allat; kutya fido; allat.mozog(); allat.mozog(5); fido.mozog(); // fido.mozog(5); // ez nem fog működni!!! fido.emlos::mozog(6); // ez működik } Mivel csak az egyiket írtuk felül, ezért csak az egyik lesz elérhető! Ugyanaz érvényes mint a konstruktoroknál, ha egyet definiálunk a fordító nem készít alap konstruktort. 38
Öröklés Általában a felhasználó Öröklött osztály Saját osztály public protected private 39
Öröklés Mi öröklődik? Minden kivéve: Konstruktor Destruktor operator= friend, barátok 40