r14-06.doc

58
 Rozdział 14. Polimorfizm Z rozdziału 12. dowiedziałeś się, jak pisać funkcje wirtualne w klasach wyprowadzonych. Jest to  jedna z podstawowy ch uiejętności potrze!ny ch przy posłu"iwaniu się polior fize, czy li o#liwości$ przypisy wania % ju# podczas działania pro"rau % specyficznych o!iekt&w klas  pochodnych do wska'nik&w wskazuj$cy ch na o!iekty klasy !azowej. Z te"o rozdziału dowiesz się( czy jest dziedziczenie wielokrotne i jak z nie"o korzystać, czy jest dziedziczenie wirtualne, czy s$ a!strakcyjne typy danych, czy s$ czyste funkcje wirtualne. Problemy z pojedynczym dziedziczeniem )rzypuśćy , #e od pewne"o czasu pracujey z naszyi klasai zwierz$t i #e podzieliliśy hierarchię klas na ptaki *Bird+ i ssaki *Mammal+. lasa Bird posiada funkcję składow$ Fly() *latanie+. lasa Mammal została podzielona na r&#ne rodzaje ssak&w, iędzy innyi na klasę Horse *ko-+. lasa Horse posiada funkcje składowe Whinny() *r#enie+ oraz Gallop() *"alopowanie+.  a"le okazuje się, #e p otrze!ujey o!iektu pe"a za * Pegasus+( skrzy#owania konia z ptakie. Pegasus o#e latać *etoda Fly()+, ale tak#e o#e r#eć *Whinny()+ i "alopować *Gallop()+. )rzy dziedziczeniu pojedynczy okazuje się, #e jesteśy w kropce. /o#ey uczynić z pe"aza o!iekt klasy Bird, ale wtedy nie !ędzie &"ł r#eć ani "alopować. /o#ey zro!ić z nie"o o!iekt Horse, ale wtedy nie !ędzie &"ł latać. )ierwsz$ pr&!$ rozwi$zania te"o pro!leu o#e !yć skopiowanie etody Fly() do klasy Pegasus i wyprowadzenie tej klasy z klasy Horse. 0ędzie to prawidłowa operacja,  przeprowadzona je dnak koszte posiada nia etody Fly() w dw&ch iejscach *w klasach Bird i Pegasus+. dy zienisz j$ w jedny iejscu, usisz paiętać o wprowadzeniu odyfikacji

Upload: greg

Post on 05-Nov-2015

215 views

Category:

Documents


0 download

TRANSCRIPT

Szablon dla tlumaczy

2

Cz I ( Podstawy obsugi systemu WhizBang (Nagwek strony)

Rozdzia 14.Polimorfizm

Z rozdziau 12. dowiedziae si, jak pisa funkcje wirtualne w klasach wyprowadzonych. Jest to jedna z podstawowych umiejtnoci potrzebnych przy posugiwaniu si polimorfizmem, czyli moliwoci przypisywania ju podczas dziaania programu specyficznych obiektw klas pochodnych do wskanikw wskazujcych na obiekty klasy bazowej.

Z tego rozdziau dowiesz si:

czym jest dziedziczenie wielokrotne i jak z niego korzysta,

czym jest dziedziczenie wirtualne,

czym s abstrakcyjne typy danych,

czym s czyste funkcje wirtualne.

Problemy z pojedynczym dziedziczeniem

Przypumy, e od pewnego czasu pracujemy z naszymi klasami zwierzt i e podzielilimy hierarchi klas na ptaki (Bird) i ssaki (Mammal). Klasa Bird posiada funkcj skadow Fly() (latanie). Klasa Mammal zostaa podzielona na rne rodzaje ssakw, midzy innymi na klas Horse (ko). Klasa Horse posiada funkcje skadowe Whinny() (renie) oraz Gallop() (galopowanie).

Nagle okazuje si, e potrzebujemy obiektu pegaza (Pegasus): skrzyowania konia z ptakiem. Pegasus moe lata (metoda Fly()), ale take moe re (Whinny()) i galopowa (Gallop()). Przy dziedziczeniu pojedynczym okazuje si, e jestemy w kropce.

Moemy uczyni z pegaza obiekt klasy Bird, ale wtedy nie bdzie mg re ani galopowa. Moemy zrobi z niego obiekt Horse, ale wtedy nie bdzie mg lata.

Pierwsz prb rozwizania tego problemu moe by skopiowanie metody Fly() do klasy Pegasus i wyprowadzenie tej klasy z klasy Horse. Bdzie to prawidowa operacja, przeprowadzona jednak kosztem posiadania metody Fly() w dwch miejscach (w klasach Bird i Pegasus). Gdy zmienisz j w jednym miejscu, musisz pamita o wprowadzeniu modyfikacji take w drugim. Oczywicie, programista, ktry kilka miesicy czy lat pniej sprbuje zmodyfikowa taki kod, take musi wiedzie o obu miejscach.

Wkrtce jednak pojawia si nowy problem. Chcemy stworzy list obiektw typu Horse oraz list obiektw typu Bird. Chcielibymy doda obiekt klasy Pegasus do dowolnej z tych list, ale gdyby Pegasus zosta wyprowadzony z klasy Horse, nie moglibymy go doda do listy obiektw klasy Bird.

Istnieje kilka rozwiza tego problemu. Moemy zmieni nazw metody Gallop() na Move() (ruch), a nastpnie przesoni metod Move() w klasie Pegasus tak, aby wykonywaa prac metody Fly(). Nastpnie przesonilibymy metod Move() innych koni tak, aby wykonywaa prac metody Gallop(). By moe pegaz byby inteligentny na tyle, by galopowa na krtkich dystansach, a lata tylko na duszych:

Pegasus::Move(long distance)

{

if (distance > veryFar)

Fly(distance);

else

Gallop(distance);

}

To rozwizanie posiada jednak pewne ograniczenia. By moe ktrego dnia pegaz zechce lata na krtkich dystansach lub galopowa na duszych. Nastpnym rozwizaniem mogoby by przeniesienie metody Fly() w gr, do klasy Horse, co zostao pokazane na listingu 14.1. Problem jednak polega na tym, i zwyke konie nie potrafi lata, wic w przypadku koni innych ni pegaz, ta metoda nie bdzie nic robi.

Listing 14.1. Gdyby konie umiay lata...

0: // Listing 14.1. Gdyby konie umiay lata...

1: // Przeniesienie metody Fly() do klasy Horse

2:

3: #include

4: using namespace std;

5:

6: class Horse

7: {

8: public:

9: void Gallop(){ cout