r12-06.doc

38
Rozdział 12. Dziedziczenie W poprzednim rozdziale poznałeś wiele zagadnień relacji związanych z projektowaniem obiektowym, włącznie m.in. z e relacj ą ę specjalizacji/ ą i generalizacji ą . Język C++ implementuje ją e poprzez dziedziczenie. W Z tym ego rozdziale łu dowiesz się: C c zym jest dziedziczenie, . W w jaki sposób wyprowadzać klasę z innej klasy, . C c zym jest chroniony dostęp chroniony i jak z niego korzystać, . C c zym są funkcje wirtualne. Czym jest dziedziczenie? Czym jest pies? Co widzisz, gdy patrzysz na swoje zwierzę? Ja widzę cztery łapy na służbie i pyska . Biolodzy widzą sieć interesujących organów, fizycy — atomy i działające różnorodne siły, zaś taksonom widzi przedstawiciela gatunku canine domesticus. Właśnie ten ostatni przypadek interesuje nas w tym momencie Skupmy się na tym ostatnim przypadku . Pies jest przedstawicielem psowatych, psowate są przedstawicielami ssaków, i tak dalej. Taksonomowie dzielą świat żywych stworzeń na królestwa, typy, klasy, rzędy, rodziny, rodzaje i gatunki. Hierarchia specjalizacji/ - generalizacji ustanawia relację typu jest- czymś. Homo sapiens jest przedstawicielem naczelnych. Taką relację

Upload: greg

Post on 16-Dec-2015

5 views

Category:

Documents


0 download

TRANSCRIPT

Szablon dla tlumaczy

2

Cz I ( Podstawy obsugi systemu WhizBang (Nagwek strony)

Rozdzia 12.Dziedziczenie

W poprzednim rozdziale poznae wiele relacji zwizanych z projektowaniem obiektowym, m.in. relacj specjalizacji/generalizacji. Jzyk C++ implementuje j poprzez dziedziczenie.

Z tego rozdziau dowiesz si:

czym jest dziedziczenie, w jaki sposb wyprowadza klas z innej klasy, czym jest dostp chroniony i jak z niego korzysta, czym s funkcje wirtualne.

Czym jest dziedziczenie?

Czym jest pies? Co widzisz, gdy patrzysz na swoje zwierz? Ja widz cztery apy i pysk. Biolodzy widz sie interesujcych organw, fizycy atomy i rnorodne siy, za taksonom widzi przedstawiciela gatunku canine domesticus.

Skupmy si na tym ostatnim przypadku. Pies jest przedstawicielem psowatych, psowate s przedstawicielami ssakw, i tak dalej. Taksonomowie dziel wiat ywych stworze na krlestwa, typy, klasy, rzdy, rodziny, rodzaje i gatunki.

Hierarchia specjalizacji/generalizacji ustanawia relacj typu jest-czym. Homo sapiens jest przedstawicielem naczelnych. Tak relacj widzimy wszdzie: wz kempingowy jest rodzajem samochodu, ktry z kolei jest rodzajem pojazdu. Budy jest rodzajem deseru, ktry jest rodzajem poywienia.

Gdy mwimy, e co jest rodzajem czego innego, zakadamym e stanowi to specjalizacj tej rzeczy. Samochd jest zatemspecjalnym rodzajem pojazdu.

Dziedziczenie i wyprowadzanie

Pies dziedziczy to jest, automatycznie otrzymuje wszystkie cechy ssaka. Poniewa jest ssakiem, porusza si i oddycha powietrzem. Wszystkie ssaki, z definicji, poruszaj si i oddychaj. Pies wzbogaca te elementy o cechy takie jak, szczekanie, machanie ogonem, zjadanie dopiero co ukoczonego rozdziau mojej ksiki, warczenie, gdy prbuj zasn... Przepraszam. Gdzie skoczyem? A, wiem:

Psy moemy podzieli na psy przeznaczone do pracy, psy do sportw i teriery, za psy do sportw moemy podzieli na psy myliwskie, spaniele i tak dalej. Mona take dokonywa dalszego podziau, na przykad psy myliwskie mona podzieli na labradory czy goldeny.

Golden jest rodzajem psa myliwskiego, ktry jest psem do sportw, nalecego do rodzaju psw, czyli bdcego ssakiem, a wic zwierzciem, czyli rzecz yw. T hierarchi przedstawia rysunek 12.1.

Rys. 12.1. Hierarchia zwierzt

C++ prbuje reprezentowa te relacje, umoliwiajc nam definiowanie klas, ktre s wyprowadzane z innych klas. Wyprowadzanie jest sposobem wyraenia relacji typu jest-czym. Now klas, Dog (pies), mona wyprowadzi z klasy Mammal (ssak). Nie musimy wtedy wyranie mwi, e pies porusza si, gdy dziedziczy t cech od ssakw.

Klasa dodajca nowe waciwoci do istniejcej ju klasy jest wyprowadzona z klasy pierwotnej. Ta pierwotna klasa jest nazywana klas bazow.

Jeli klasa Dog jest wyprowadzona z klasy Mammal, oznacza to, e klasa Mammal jest klas bazow (nadrzdn) klasy Dog. Klasy wyprowadzone (pochodne) stanow nadzbir swoich klas bazowych. Pies przejmuje swoje cechy od ssakw, tak klasa Dog przejmie pewne metody lub dane klasy Mammal.

Zwykle klasa bazowa posiada wicej ni jedn klas pochodn. Poniewa zarwno psy, jak i koty oraz konie s ssakami, wic ich zostay byy wyprowadzone z klasy Mammal.

Krlestwo zwierzt

Aby uatwi przedstawienie procesu dziedziczenia i wyprowadzania, w tym rozdziale skupimy si na zwizkach pomidzy rnymi klasami reprezentujcymi zwierzta. Moesz sobie wyobrazi, e bawimy si w dziecic gr symulacj farmy.

Opracujemy cay zestaw zwierzt, obejmujcy konie, krowy, psy, koty, owce, itd. Stworzymy metody dla tych klas, aby zwierzta mogy funkcjonowa tak, jak oczekiwaoby tego dziecko, ale na razie kad z tych metod zastpimy zwyk instrukcj wydruku.

Minimalizowanie funkcji (czyli pozostawienie tylko jej szkieletu) oznacza, e napiszemy tylko tyle kodu, ile wystarczy do pokazania, e funkcja zostaa wywoana. Szczegy pozostawimy na pniej, gdy bdziemy mie wicej czasu. Jeli tylko masz ochot, moesz wzbogaci minimalny kod zaprezentowany w tym rozdziale i sprawi, by zwierzta zachowyway si bardziej realistycznie.

Skadnia wyprowadzania

Gdy deklarujesz klas, moesz wskaza klas, od ktrej pochodzi, zapisujc po nazwie tworzonej klasy dwukropek, rodzaj wyprowadzania (publiczny lub inny) oraz klas bazow. Oto przykad:

class Dog : public Mammal

Rodzaj wyprowadzania opiszemy w dalszej czci rozdziau. Na razie bdziemy uywa wyprowadzania publicznego (oznaczonego sowem kluczowym public). Klasa bazowa musi by zdefiniowana wczeniej, gdy w przeciwnym razie kompilator zgosi bd. Listing 12.1 ilustruje sposb deklarowania klasy Dog, wyprowadzonej z klasy Mammal.

Listing 12.1. Proste dziedziczenie

0: //Listing 12.1 Proste dziedziczenie

1:

2: #include

3: using namespace std;

4:

5: enum BREED { GOLDEN, CAIRN, DANDIE, SHETLAND, DOBERMAN, LAB };

6:

7: class Mammal

8: {

9: public:

10: // konstruktory

11: Mammal();

12: ~Mammal();

13:

14: //akcesory

15: int GetAge() const;

16: void SetAge(int);

17: int GetWeight() const;

18: void SetWeight();

19:

20: //inne metody

21: void Speak() const;

22: void Sleep() const;

23:

24:

25: protected:

26: int itsAge;

27: int itsWeight;

28: };

29:

30: class Dog : public Mammal

31: {

32: public:

33:

34: // konstruktory

35: Dog();

36: ~Dog();

37:

38: // akcesory

39: BREED GetBreed() const;

40: void SetBreed(BREED);

41:

42: // inne metody

43: WagTail();

44: BegForFood();

45:

46: protected:

47: BREED itsBreed;

48: };

Ten kod nie wywietla wynikw, gdy zawiera jedynie zestaw deklaracji klas (bez ich implementacji). Mimo to mona w nim wiele zobaczy.

AnalizaW liniach od 7. do 28. deklarowana jest klasa Mammal (ssak). Zwr uwag, e w tym przykadzie klasa Mammal nie jest wyprowadzana z adnej innej klasy. W realnym wiecie ssaki pochodz od (to znaczy, e s rodzajem) zwierzt. W programie C++ moesz zaprezentowa jedynie cz informacji, ktre posiadasz na temat danego obiektu. Rzeczywisto jest zdecydowanie zbyt skomplikowana, aby uchwyci j w caoci, wic kada hierarchia w C++ jest umown reprezentacj dostpnych danych. Sztuka dobrego projektowania polega na reprezentowaniu interesujcych nas obszarw tak, aby reprezentoway rzeczywisto w moliwie najlepszy sposb.

Hierarchia musi si gdzie zaczyna; w tym programie rozpoczyna si od klasy Mammal. Z powodu tego, pewne zmienne skadowe, ktre mogy nalee do wyszej klasy, nie s tu reprezentowane. Wszystkie zwierzta z pewnoci posiadaj na przykad wag i wiek, wic jeli klasa Mammal byaby wyprowadzona z klasy Animal (zwierz), moglibymy oczekiwa, e dziedziczy te atrybuty. Jednak w naszym przykadzie atrybuty te wystpuj w klasie Mammal.

Aby zachowa niewielk i spjn posta programu, w klasie Mammal zostao umieszczonych jedynie sze metod cztery akcesory oraz metody Speak() (mwienie) i Sleep() (spanie).

Klasa Dog (pies) dziedziczy po klasie Mammal, co wskazuje linia 30. Kady obiekt typu Dog bdzie posiada trzy zmienne skadowe: itsAge (wiek), itsWeight (waga) oraz itsBread (rasa). Zwr uwag, e deklaracja klasy Dog nie obejmuje zmiennych skadowych itsAge oraz itsWeight. Obiekty klasy Dog dziedzicz te zmienne od klasy Mammal, razem z metodami tej klasy (z wyjtkiem operatora kopiujcego oraz destruktora i konstruktora).

Prywatne kontra chronione

By moe w liniach 25. i 46. listingu 12.1 zauwaye nowe sowo kluczowe dostpu, protected (chronione). Wczeniej dane klasy byy deklarowane jako prywatne. Jednak prywatne skadowe nie s dostpne dla klas pochodnych. Moglibymy uczyni zmienne itsAge i itsWeight skadowymi publicznymi, ale nie byoby to podane. Nie chcemy, by inne klasy mogy bezporednio odwoywa si do tych danych skadowych.

UWAGAIstnieje powd, by wszystkie dane skadowe klasy oznacza jako prywatne, a nie jako chronione. Powd ten przedstawi Stroustrup (twrca jzyka C++) w swojej ksice The Design and Evolution of C++, ISBN 0-201-543330-3, Addison Wesley, 1994. Metody chronione nie s jednak uwaane za kopotliwe i mog by bardzo uyteczne.

Potrzebujemy teraz oznaczenia, ktre mwi: Uczy te zmienne widocznymi dla tej klasy i dla klas z niej wyprowadzonych. Takim oznaczeniem jest wanie sowo kluczowe protected chroniony. Chronione funkcje i dane skadowe s w peni widoczne dla klas pochodnych i nie s dostpne dla innych klas.

Istniej trzy specyfikatory dostpu: publiczny (public), chroniony (protected) oraz private (prywatny). Jeli funkcja posiada obiekt twojej klasy, moe odwoywa si do wszystkich jej publicznych funkcji i danych skadowych. Z kolei funkcje skadowe klasy mog odwoywa si do wszystkich prywatnych funkcji i danych skadowych swojej wasnej klasy, oraz do wszystkich chronionych funkcji i danych skadowych wszystkich klas, z ktrych ich klasa jest wyprowadzona.

Tak wic, funkcja Dog::WagTail() (macha ogonem) moe odwoywa si do prywatnej danej itsBreed oraz do prywatnych danych klasy Mammal.

Nawet gdyby pomidzy klas Mammal, a klas Dog wystpoway inne klasy (na przykad DomesticAnimals zwierzta domowe), klasa Dog w dalszym cigu mogaby si odwoywa do prywatnych skadowych klasy Mammal, zakadajc e wszystkie inne klasy uywayby dziedziczenia publicznego. Dziedziczenie prywatne zostanie omwione w rozdziale 16., Dziedziczenie zaawansowane.

Listing 12.2 przedstawia sposb tworzenia obiektw typu Dog oraz dostpu do danych i funkcji zawartych w tym typie.

Listing 12.2. Uycie klasy wyprowadzonej 0: //Listing 12.2 Uycie klasy wyprowadzonej 1:

2: #include

3: using std::cout;

4:

5: enum BREED { GOLDEN, CAIRN, DANDIE, SHETLAND, DOBERMAN, LAB };

6:

7: class Mammal

8: {

9: public:

10: // konstruktory

11: Mammal():itsAge(2), itsWeight(5){}

12: ~Mammal(){}

13:

14: //akcesory

15: int GetAge() const { return itsAge; }

16: void SetAge(int age) { itsAge = age; }

17: int GetWeight() const { return itsWeight; }

18: void SetWeight(int weight) { itsWeight = weight; }

19:

20: //inne metody

21: void Speak()const { cout