1 Programowanie obiektowe PO PO - LAB 2 Wojciech Pieprzyca
2 Dziedziczenie w swej istocie polega na definiowaniu nowej klasy przy użyciu klasy, która już wcześniej istniała. Czasami nie ma konieczności definiowania czegoś zupełnie od początku, można posłużyć się dobrze działającą i przetestowaną klasą, która będzie stanowiła podstawę do budowy i rozwoju kolejnej klasy. Klasę z której dziedziczymy jej składowe i metody nazywamy klasą bazową. Klasę, która dziedziczy te elementy nazywamy klasą pochodną. Innymi słowy klasa pochodna dziedziczy składowe i metody po klasie bazowej. A zatem klasa pochodna będzie mogła mieć dostęp do składowych i metod zdefiniowanych w klasie bazowej, czyli nie będzie trzeba ich powtórnie definiować w klasie pochodnej, co już samo w sobie jest zaletą. Dziedziczenie (I) PO
3 Naszym celem jest określenie następującej hierarchii klas: Dziedziczenie (II) PO Zwierze *nazwa, iloscNog * jedz() * spij() Ssak * futro * pijMleko() * rozmazaj() waleczneSerce * szukaj() * poluj() Ptak * lec() * spiewaj() Pies * rodzajSiersci * rozmnazanie() Orzel
4 Jak zapisać to w języku C++ ? class nazwaKlasyBazowej { //definicje składowych i metod klasy bazowej }; class nazwaKlasyPochodnej : kwalifikatorDostepu nazwaKlasyBazowej { //definicje składowych i metod klasy pochodnej } Różnica przy definiowaniu klasy pochodnej polega na tym iż w nagłówku po nazwie klasy podajemy listę klas bazowych po których klasa pochodna ma dziedziczyć. Dodatkowo określamy tzw. kwalifikator dostępu, który będzie określał jak mają być dziedziczone składowe public i protected z klas bazowych. Dziedziczenie (III) PO
5 Jak wykorzystywać kwalifikatory dostępu ? W klasie bazowej istnieją składowe i metody, które mają określony dostęp jako publiczny (public), chroniony (protected) lub prywatny (private). Pozostaje pytaniem otwartym jaki dostęp do tych składowych i metod ma być określony w nowo definiowanej klasie (klasie pochodnej). Jednej rzeczy możemy być pewni. Wszystkie elementy klasy bazowej z dostępem private zostaną odziedziczone jako prywatne tzn. dostęp do nich będzie taki jakbyśmy zdefiniowali je w sekcji private klasy pochodnej. Natomiast elementy klasy bazowej z dostępem protected lub public mogą być dziedziczone na różne sposoby. I w tym celu wykorzystuje się kwalifikator dostępu. Możemy zatem określić iż składowe i metody klasy bazowej z dostępem public i protected będą w klasie pochodnej miały określone dostęp jako: public, lub protected, lub private. Dziedziczenie (IV) PO
6 Prosty przykład class podstawowa { public: void wolaj(); protected: char tab[20]; private: float oc; }; class rozszerzona : public podstawowa { }; Klasa rozszerzona będzie dziedziczyła składową oc jako private (ponieważ wszystkie elementy private dziedziczone są zawsze jako prywatne). Kwalifikator dostępu public określa natomiast iż metoda wolaj() i składowa tab będą odziedziczone jako public. Dziedziczenie (V) PO
7 Definicja struktury klas z diagramu class Zwierze { private: char nazwa[20]; int iloscNog; public: Zwierze(char *_nazwa, int _iloscNog); void jedz(); void spij(); }; Zwierze::Zwierze(char *_nazwa, int _iloscNog) { strcpy(nazwa,_nazwa); iloscNog = _iloscNog; cout
8 void Zwierze::jedz() { cout
9 class Ptak : public Zwierze { public: Ptak(char *nazwa, int nog); void lec(); void spiewaj(); }; Ptak::Ptak(char *nazwa, int nog) : Zwierze(nazwa,nog) { cout
10 void Ptak::lec() { cout
11 class Ssak : public Zwierze { private: bool futro; public: Ssak(char *nazwa, int nog); void pijMleko(); protected: void rozmnazaj(); }; Ssak::Ssak(char *nazwa, int nog) : Zwierze(nazwa,nog) { cout
12 void Ssak::pijMleko() { cout
13 class WaleczneSerce { public: void szukaj(); void poluj(); }; void WaleczneSerce::szukaj() { cout
14 class Pies : public Ssak, public WaleczneSerce { private: char rodzajSiersci[20]; public: Pies(char *nazwa, int nog); void rozmnazanie() { rozmnazaj(); } }; Pies::Pies(char *nazwa, int nog) : Ssak(nazwa,nog) { cout
15 class Pies2 : public Ssak, protected WaleczneSerce { private: char rodzajSiersci[20]; public: Pies2(char *nazwa, int nog); void rozmnazanie() { rozmnazaj(); } }; Pies2::Pies2(char *nazwa, int nog) : Ssak(nazwa,nog) { cout
16 class Orzel : public Ptak, public WaleczneSerce { public: Orzel(char *nazwa, int nog); }; Orzel::Orzel(char *nazwa, int nog) : Ptak(nazwa,nog) { cout
17 int main(int argc, char *argv[]) { Zwierze zwierz("swidrzyk lamliwy",1); zwierz.jedz(); zwierz.spij(); cout
18 Ssak ssak("niedzwiedz",4); ssak.jedz();//metody jedz i spij z klasy Zwierze ssak.spij(); ssak.pijMleko();//metoda pijMleko z klasy Ssak //ssak.rozmnazaj(); //nie da sie poniewaz ta metoda jest protected cout
19 Pies2 pies2("jamnik",4); //pies2.szukaj(); //nie da sie poniewaz te metody zostaly odziedziczone //pies2.poluj(); //jako protected cout