LEKCJA 27: O DZIEDZICZENIU. ________________________________________________________________ W trakcie tej lakcji dowiesz si� na czym polega dziedziczenie. ________________________________________________________________ Dziedziczenie (ang inheritance) jest pr�b� na�ladowania w technice programowania najcenniejszego bodaj wynalazku Matki Natury - zdolno�ci przekazywania cech. Je�li wyobrazimy sobie typy struktur konik, lew, s�o�, czy krokodyl, to jest oczywiste, �e struktury te b�d� posiada� wiele wsp�lnych cech. Wsp�lnymi cechami mog� by� zar�wno wsp�lne dane (parametry) - np. nogi = 4; jak i wsp�lne wykonywane przez nie funkcje - np. jedz(), �pij(), oddychaj() itd.. Mog� wyst�powa� oczywi�cie i r�nice, ale wiele danych i funkcji oka�e si� wsp�lnych. LOGIKA DZIEDZICZENIA. Rozwijaj�c dalej my�l naszkicowan� we wst�pie, w kategoriach obiegowego j�zyka naturalnego mo�na rzec, �e s�o� Trombalski by�by tu struktur� typu formalnego S�o�. Funkcjami wewn�trznymi s�onia Trombalskiego i np. krokodyla Eugeniusza mog�yby by� wsp�lne czynno�ci tych struktur (lub obiekt�w): jedz() �pij() oddychaj() Projektanci C++ wpadli na pomys� na�ladowania mechanizmu dziedziczenia. Zamiast tworzy� te wszystkie struktury oddzielnie, mo�emy zdefiniowa� w C++ jeden og�lny typ struktur (ang. generic structure), nazywany inaczej STRUKTUR� BAZOW� (ang. base structure). Wszystkie wymienione wy�ej struktury (s�o�, krokodyl, itp.) sta�yby si� wtedy strukturami pochodnymi (ang. derived structures). Nasza struktura bazowa mog�aby nazywa� si� zn�w np. Zwierzak. Poniewa� niekt�re funkcje s� wsp�lne dla wszystkich struktur (wszystkie Zwierzaki musz� je��, spa�, itp.), mogliby�my przyj��, �e ka�da struktura pochodna od bazowego typu Zwierzak musi zawiera� funkcje jedz(), spij() i oddychaj(). Je�li zdefiniujemy struktur� bazow� Zwierzak i zadeklarujemy w tej klasie funkcje jedz(), spij() i oddychaj(), mo�emy spodziewa� si�, �e struktura pochodna s�o� powinna odziedziczy� funkcje - cechy po strukturze bazowej Zwierzak. . S�o� mo�e oczywi�cie mie� i swoje odr�bne cechy - dane i funkcje - np.: Slon.flaga_ssak Slon.trabie() Slon.tupie() "Gramatyka" C++ przy opisywaniu wzajemnego pokrewie�stwa struktur (i klas) wygl�da nast�puj�co: struct NazwaStrukturyPochodnej : NazwaStrukturyBazowej { private: Lista danych i funkcji prywatnych public: Lista danych i funkcji publicznych } Lista struktur danego typu; a dla klas i obiekt�w: class NazwaKlasyPochodnej : dost�p NazwaKlasyBazowej { Lista danych i funkcji prywatnych public: Lista danych i funkcji publicznych } Lista obiektow danej klasy; Bazowy typ struktur w C++ wygl�da�aby tak: struct Zwierzak { void jedz(); void spij(); void oddychaj(); }; Je�li chcemy zasygnalizowa�, �e pochodny typ struktur Slon ma odziedziczy� co� po typie bazowym Zwierzak, musimy w definicji klasy pochodnej poda� nazw� klasy bazowej (je�li mamy dziedziczy� - nale�y wskaza� po kim): struct Slon : Zwierzak { int trabie(); int tupie(); }; Przed nazw� typu struktury (klasy) bazowej (tu: Zwierzak) mo�e pojawi� si� s�owo okre�laj�ce zasady dost�pu do danych i funkcji (tu: public). [!!!] RӯNIE MO�NA DZIEDZICZY�... ________________________________________________________________ * Je�li u�yjemy w tym miejscu s�owa public (przy strukturach domy�lne), to atrybuty dost�pu zostan� odziedziczone wprost. Oznacza to, �e to, co by�o prywatne w strukturze bazowej zostanie przeniesione jako prywatne do struktury pochodnej, a to, co by�o publiczne w strukturze bazowej zostanie przeniesione jako publiczne do struktury pochodnej. * Je�li natomiast u�yjemy w tym miejscu s�owa private, to wszystko, co struktura pochodna odziedziczy po strukturze bazowej stanie si� w strukturze pochodnej prywatne. ________________________________________________________________ Opracowanie przyk�adowego programu ilustruj�cego mechanizm dziedziczenia rozpoczniemy od zdefiniowania bazowego typu struktur i struktury pochodnej. struct Zwierzak { int nogi; <-- dane void jedz(); <-- funkcje void spij(); void oddychaj(); }; struct Slon : Zwierzak { int flaga_ssak; int trabie(); int tupie(); }; Zdefiniujemy teraz wszystkie funkcje nale��ce do powy�szych struktur. Funkcje b�d� tylko zg�asza� si� na ekranie napisem, by prze�ledzi� kolejno�� ich wywo�ania. void Zwierzak::jedz(void) { cout << "Jem conieco...\n"; } void Zwierzak::spij(void) { cout << "Cosik mi sie sni...\n"; } void Zwierzak::oddychaj(void) { cout << "Dysz� cie�ko...\n"; } void Slon::trabi(void) { cout << "Tra-ta-ta...\n"; } void Slon::tupie(void) { cout << "Kroczem...na zach�d\n"; } Aby przekona� si�, co struktura typu Slon rzeczywi�cie odziedziczy "po przodku", zredagujemy program g��wny. # include <iostream.h> ... void main() { Slon Choleryk; //Deklaracja struktury ... cout << "\nNogi odziedziczylem: " << Choleryk.nogi; cout << "\nA teraz kolejno funkcje: \n"; Choleryk.jedz(); Choleryk.spij(); Choleryk.oddychaj(); Choleryk.trabi(); Choleryk.tupie(); } Mimo, �e tworz�c struktur� S�o� nie zadeklarowali�my w jej sk�adzie ani funkcji jedz(), ani spij(), ani danych nogi, mo�emy zastosowa� funkcj� Choleryk.jedz(), poniewa� Choleryk odziedziczy� t� funkcj� po strukturze bazowej Zwierzak. Dzi�ki dziedziczeniu mo�emy pos�ugiwa� si� danymi i funkcjami nale��cymi do obu typ�w struktur - bazowego: Zwierzak i pochodnego: Slon. [???] A CO Z UNIAMI ? _______________________________________________________________ Unie nie mog� bra� udzia�u w dziedziczeniu. Unia nie mo�e by� ani typem bazowym ani typem pochodnym. _______________________________________________________________ Program w ca�o�ci b�dzie wygl�da� tak: [P099.CPP] # include <iostream.h> struct Zwierzak { int nogi; void jedz(); void spij(); void oddychaj(); }; void Zwierzak::jedz(void) { cout << "Jem conieco...\n"; } void Zwierzak::spij(void) { cout << "Cosik mi sie sni...\n"; } void Zwierzak::oddychaj(void) { cout << "Dysze ciezko...\n"; } struct Slon : Zwierzak { int flaga_ssak; void trabi(); void tupie(); }; void Slon::trabi(void) { cout << "Tra-ta-ta...\n"; } void Slon::tupie(void) { cout << "Kroczem...na wschod\n"; } void main() { Slon Choleryk; Choleryk.nogi = 4; Choleryk.flaga_ssak = 1; cout << "\nNogi odziedziczylem: " << Choleryk.nogi; cout << "\nA teraz kolejno funkcje: \n"; Choleryk.jedz(); Choleryk.spij(); Choleryk.oddychaj(); Choleryk.trabi(); Choleryk.tupie(); if(Choleryk.flaga_ssak == 1) cout << "SSak!"; }
ZAZZY