Dziedziczenie 245
Dziedziczenie 245
destruktor Psa. .
destruktor Ssaka destruktor Ssaka
W linii 34 klasa Pies nadpisuje metodę Mow () tak, aby każdy obiekt
klasy Pies szczekał (wypisywał na ekranie Hau!) w momencie wywołania metody Mow(). W linii 42 jest tworzony obiekt klasy Ssak o nazwie duzeZwierze (pierwsza linia wydruku wyjściowego to efekt wywołania konstruktora klasy Ssak). W linii 43 tworzymy obiekt klasy Pies (dwie kolejne linie wydruku to efekt wywołania kolejno konstruktora klasy Ssak i konstruktora klasy Pies).
W linii 44 obiekt klasy Ssak wywołuje swoją metodę Mow(). Podobnie obiekt klasy Pies w linii 45. Linie wydruku świadczą o tym, że zostały wywołane właściwe, dla każdej klasy, metody. Na koniec, podczas usuwania obydwu stworzonych obiektów z pamięci, zostają wywołane destruktory klas.
Obie metody dają podobne efekty. Kiedy przeciążasz metodę to tworzysz kilka różnych metod o tej samej nazwie i o różnej sygnaturze (wartość zwracana, lista parametrów). Kiedy nadpisujesz metodę to tworzysz w klasie pochodnej metodę, która zastępuje metodę z klasy bazowej.
W ostatnim programie, metoda klasy Pies o nazwie Mow() ukryła metodę klasy bazowej. O to nam chodziło, ale istnieje możliwość zaistnienia pewnego efektu ubocznego. Jeśli klasa Ssak miałaby przeciążoną metodę Ruch (), którą byśmy nadpisali w klasie Pies, to zostałyby ukryte wszystkie przeciążone metody Ruch() w klasie Ssak.
Jeśli klasa Ssak miałaby trzy metody przeciążające funkcję Ruch() - jedną nie pobierająca parametrów, druga pobierającą wartość całkowitą i trzecią dwuargu-mentową i jeśli klasa Pies nadpisałaby metodę Ruch() funkcją nie pobierającą parametrów to dostęp do pozostałych dwóch metod z klasy Ssak byłby bardzo utrudniony. Listing 16.6 ilustruje ten problem.
2:
3:
4:
5:
6:
7:
8:
9:
10
1: //Listing 16.6 Ukrywanie metod
#include <iostream.h>
class Ssak {
public:
void Ruch() const { cout « "Ssak przeszedł jeden krok\n"; ) void Ruch(int distance) const
{ cout « "Ssak przeszedł " « distance «" kroki. \n"; }
destruktor Psa... destruktor Ssaka... destruktor Ssaka...
ANALIZA
W linii 34 klasa Pies nadpisuje metodę Mow() tak, aby każdy obiekt I klasy Pies szczeka! (wypisywał na ekranie Hau!) w momencie wywołania metody Mow (). W linii 42 jest tworzony obiekt klasy Ssak o nazwie duzeZwierze (pierwsza linia wydruku wyjściowego to efekt wywołania konstruktora klasy Ssak). W linii 43 tworzymy obiekt klasy Pies (dwie kolejne linie wydruku to efekt wywołania kolejno konstruktora klasy Ssak i konstruktora klasy Pies).
W linii 44 obiekt klasy Ssak wywołuje swoją metodę Mow(). Podobnie obiekt klasy Pies w linii 45. Linie wydruku świadczą o tym, że zostały wywołane właściwe, dla każdej klasy, metody. Na koniec, podczas usuwania obydwu stworzonych obiektów z pamięci, zostają wywołane destruktory klas.
Obie metody dają podobne efekty. Kiedy przeciążasz metodę to tworzysz kilka różnych metod o tej samej nazwie i o różnej sygnaturze (wartość zwracana, lista parametrów). Kiedy nadpisujesz metodę to tworzysz w klasie pochodnej metodę, która zastępuje metodę z klasy bazowej.
W ostatnim programie, metoda klasy Pies o nazwie Mow () ukryła metodę klasy bazowej. O to nam chodziło, ale istnieje możliwość zaistnienia pewnego efektu ubocznego. Jeśli klasa Ssak miałaby przeciążoną metodę Ruch(), którą byśmy nadpisali w klasie Pies, to zostałyby ukryte wszystkie przeciążone metody Ruch() w klasie Ssak.
Jeśli klasa Ssak miałaby trzy metody przeciążające funkcję Ruch() - jedną nie pobierająca parametrów, druga pobierającą wartość całkowitą i trzecią dwuargu-mentową i jeśli klasa Pies nadpisałaby metodę Ruch() funkcją nie pobierającą parametrów to dostęp do pozostałych dwóch metod z klasy Ssak byłby bardzo utrudniony. Listing 16.6 ilustruje ten problem.
1: //Listing 16.6 Ukrywanie metod
2:
3: ttinclude <ios tream. h>
4:
5: class Ssak
6: {
7: public:
8: void Ruch() const { cout « "Ssak przeszedł jeden krok\n"; )
9: void Ruch(int distance) const
10: ( cout « "Ssak przeszedł " « distance «" kroki. \n"; }