Materiały: Informatyka II Laboratorium : Programowania obiektowe C++ - dziedziczenie Książka: Symfonia C++, Jerzy Grębosz. Wykład: www.materialy.prz-rzeszow.pl, Informatyka II, dr Wojciech Rząsa. Zasoby WWW: http://pl.wikibooks.org/wiki/c++, http://www.cplusplus.com. Wujek google. Zrealizuj poniższe zadania jeśli masz jakiś problem to zapytaj prowadzącego.. Prosty przykład dziedziczenia klasy C++: 0 class KlasaBazowa KlasaBazowa() a = 0; ; class KlasaPochodna : public KlasaBazowa int b; ; KlasaPochodna kp; kp.a = ; kp.b = ; endl; endl; cout << "Wartosc pola a: " << kp.a << cout << "Wartosc pola a: " << kp.b << return 0; Dziedziczenie daje możliwość wykorzystania nowych klas w oparciu o stare klasy. Nowa klasa (pochodna) powiększa możliwości innej (wcześniejszej) klasy (bazowej). zdefiniowanie klasy bazowej: konstruktor bezargumentowy jedno pole publiczne typu int zdefiniowanie klasy KlasaPochodna, dziedziczącej z KlasaBazowa: typ dziedziczenia public (są jeszcze private, protected), klasa z bazowa z której dziedziczy się metody i pola nie zapominaj o dwukropku!!! klasa pochodna ma jedno pole typu int z etykietą public utworzenie obiektu klasy pochodnej: obiekt kp ma pole b zdefiniowane w klasie również odziedziczył po klasie bazowej pole a!!!!
. Etykiety dziedziczenia, etykiety klasy bazowej, a dostępność pól i metod klasy bazowej w klasie pochodnej: Typy dziedziczenia: public - oznacza, że dziedziczone metody i pola mają taką widoczność jak w klasie bazowej: public public protected protected private brak dostępu w klasie pochodnej protected- oznacza, że pole/metody publiczne zmieniają się w chronione: public protected protected protected private brak dostępu w klasie pochodnej private- oznacza, że wszystkie elementy klasy bazowej zmieniają się w prywatne dla klasy pochodnej: public private protected private private brak dostępu w klasie pochodnej brak operatora - oznacza, że niejawnie (domyślnie) zostanie wybrany typ dziedziczenia private. Przykład: 0 class KlasaBazowa KlasaBazowa() a; ; class KlasaPochodna : public KlasaBazowa int b; KlasaPochodna() b = 0; void Drukuj() cout << "Pole klasy bazowej a: " << a << endl; cout << "Polde klasy pochodnej b: " << b << endl; ; zdefiniowanie klasy bazowej: konstruktor bezargumentowy jedno pole publiczne zdefiniowanie klasy pochodnej: dziedziczy z klasy KlasaBazowa dziedziczenie public jedno pole public (lin. ) utworzenie metody Drukuj(), która wypisuje wartość pól klasy bazowej i pochodnej pole klasy bazowej a: - etykieta public w klasie bazowej - dziedziczenia public - w związku z tym to pole w klasie pochodnej jest dostępne z etykietą public (na zewnątrz i wewnątrz klasy) utworzenie obiektu klasy pochodnej (linia ) użycie metody drukuj (lin. ).Zamień linijkę :
KlasaPochodna kp; kp.a = ; kp.b = ; kp.drukuj(); return 0; na protected: Spróbuj zbudować program: Pole z etykietą protected w klasie bazowej jest dostępne w klasie pochodnej z etykietę private (tylko wewnątrz klasy) pojawi się błąd w trakcie budowania programu odnoszący się do instrukcji: kp.a = ;. Zamień etykietę protected na private dla pola a i spróbuj zbudować program: Pole z etykietą private klasy bazowej nie jest w ogóle dostępne w klasie pochodnej ani na zewnątrz ani wewnątrz klasy. Pojawią się dwa błędy odnoszące się do linii: kp.a = ; oraz cout << "Pole klasy bazowej a: " << a << endl; Tu wychodzi różnica dla etykiet pól/metod protected i private: gdy nie ma dziedziczenia, to mają takie same działanie czyli dostęp pól/metod wewnątrz klasy gdy jest dziedziczenie, to pola z etykietą private nie podlegają dziedziczeniu nie są dostępne w klasie pochodnej, natomiast protected podlegają i są dostępne w klasie pochodnej tylko wewnątrz klasy
. Dziedziczenie, a konstruktory: 0 class KlasaBazowa KlasaBazowa(int _a) a = _a; protected: ; class KlasaPochodna : public KlasaBazowa KlasaPochodna(int _a, int _b) : KlasaBazowa(_a) b = _b; void Drukuj() cout << "Pole klasy bazowej a: " << a << endl; cout << "Pole klasy pochodnej b: " << b << endl; private: int b; ; KlasaPochodna kp(,); kp.drukuj(); return 0; zdefiniowanie klasy bazowej: konstruktor z parametrem, ustawiający pole a jedno pole protected utworzenie klasy pochodnej: dziedziczenie public konstruktor dwuparametrowy - jeden parametr do ustawiania pola klasy pochodnej - drugi do ustawiania klasy bazowej - w celu ustawienia pola a, wywoływany jest konstruktor klasy bazowej (dwukropek i wywołanie bezpośrednie konstruktora klasy bazowej z parametrem) jeśli klasa bazowa nie posiada konstruktora bez parametru, to klasa pochodna musi wywołać konstruktor klasy bazowej!!!!!!!!!!! wciąż możliwe jest przeciążanie konstruktorów dla klasy bazowej
. Zadanie do zrealizowania: a) Dopisz metodę do klasy Trojkat z poprzednich zajęć: UstawPole prywatna metoda ustawiające pole (pole trójkąta). Napisz klasę TrojkatR (klasa pochodna, trójkąt równoboczny), która dziedziczy w sposób public z klasy Trojkat (klasa bazowa). Klasa posiada następujące metody: Konstruktor- jednoargumentowy, przyjmuje jeden argument bok trójkąta równobocznego, konstruktor musi wywołać konstruktor klasy bazowej, ObliczPole publiczna metoda obliczająca i ustawiająca pole (pola klasy bazowej) za pomocą metody UstawPole oraz zwracająca wartość pola trójkąta, pole trójkąta należy obliczyć ze wzoru: pole = a*a*sqrt()/, długość boku należy pobrać za pomocą odpowiedniej metody. b) Napisać funkcję main w której należy: - utworzyć obiekt klasy Trojkat, - obliczyć i wydrukować wartość pola trójkąta, - utworzyć obiekt klasy TrojkatR, - obliczyć i wydrukować wartość pola trójkąta równobocznego. c) Rozszerzyć działanie klas Trojkat oraz TrojkatR, tak aby możliwe było obliczanie obwodu analogiczne do obliczania pola trójkąta. Przykładowe rozwiązanie dla a) i b): 0 #include <math.h> class Trojkat private: float x, y, z; float obw; float pole; Trojkat(); Trojkat(Trojkat& trojkat); Trojkat(float _x, float _y, float _z) if(sprawdzxyz(_x, _y, _z)) x = _x; y = _y; z = _z; else x = y = z = 0; static bool SprawdzXYZ(float _x, float _y, float _z); void UstawXYZ(float _x, float _y, float _z);
0 0 0 0 0 private: void ObliczObw(); float ObliczPole(); float ZwrocX(); // dokończyć samemu ZwrocY, ZwrocZ, ZwrocPole, ZwrocObw void UstawPole(float _pole) pole = _pole; ; class TrojkatR : public Trojkat TrojkatR(float a) : Trojkat(a, a, a) float ObliczPole() float a = ZwrocX(); float p = a*a* sqrt(.0)/; UstawPole(p); return p; ; Trojkat t(,,); cout << "Pola trojkata wynosi: " << t.obliczpole() << endl; TrojkatR t(); cout << "Pole trojkata równobocznego wynosi: " << t.obliczpole() << endl; Trojkat::Trojkat() x = y = z = obw = pole = 0; Trojkat::Trojkat(Trojkat& t) x = t.x; y = t.y; z = t.z; obw = t.obw; pole = t.pole; bool Trojkat::SprawdzXYZ(float _x, float _y, float _z) if(_x > 0 && _y > 0 && _z > 0) if((_x + _y > _z) && (_y + _z > _x) && (_x + _z > _y)) return true; return false; void Trojkat::UstawXYZ(float _x, float _y,
0 00 0 0 0 0 0 0 0 0 0 float _z) if(sprawdzxyz(_x, _y, _z)) x = _x; y = _y; z = _z; void Trojkat::ObliczObw() obw = (x + y + z) / ; float Trojkat::ObliczPole() ObliczObw(); pole = sqrt(obw*(obw - x) * (obw - y) * (obw - z)); return pole; float Trojkat::ZwrocX() return x;