Lab 3 - lab3_-_programowanie_obiektowe_c++

Transkrypt

Lab 3 - lab3_-_programowanie_obiektowe_c++
Informatyka II
Laboratorium 3 : Programowania obiektowe C++ dziedziczenie
Materiały:
•
•
•
•
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.
1. Prosty przykład dziedziczenia klasy C++:
Linia Kod programu
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <iostream>
using namespace std;
class KlasaBazowa
{
public:
KlasaBazowa()
{
a = 0;
}
int a;
};
class KlasaPochodna : public KlasaBazowa
{
public:
int b;
};
int main()
{
KlasaPochodna kp;
kp.a = 5;
kp.b = 4;
Komentarz
•
•
•
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
cout << "Wartosc pola a: " << kp.a <<
endl;
endl;
}
cout << "Wartosc pola a: " << kp.b <<
system("pause");
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).
•
utworzenie obiektu klasy
pochodnej:
◦ obiekt kp ma pole b
zdefiniowane w klasie
◦ również odziedziczył po
klasie bazowej pole a!!!!
2. 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:
➢
Linia Kod programu
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
Komentarz
#include <iostream>
using namespace std;
•
class KlasaBazowa
{
public:
KlasaBazowa()
{
a;
}
int a;
};
class KlasaPochodna : public KlasaBazowa
{
public:
int b;
KlasaPochodna()
{
b = 0;
}
void Drukuj()
{
cout << "Pole klasy bazowej a: "
<< a << endl;
cout << "Polde klasy pochodnej
b: " << b << endl;
}
•
};
int main()
zdefiniowanie klasy bazowej:
◦ konstruktor bezargumentowy
◦ jedno pole publiczne
zdefiniowanie klasy pochodnej:
◦ dziedziczy z klasy
KlasaBazowa
dziedziczenie public
◦ jedno pole public (lin. 16)
◦ 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 30)
użycie metody drukuj (lin. 33)
1.Zamień linijkę 11:
29
30
31
32
33
34
35
36
37
{
KlasaPochodna kp;
kp.a = 5;
kp.b = 4;
kp.Drukuj();
system("pause");
return 0;
}
int a;
na
protected:
int a;
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 =
5;
2. 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 = 5;
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
3. Dziedziczenie, a konstruktory:
Linia Kod programu
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <iostream>
using namespace std;
class KlasaBazowa
{
public:
KlasaBazowa(int _a)
{
a = _a;
}
protected:
int a;
};
class KlasaPochodna : public KlasaBazowa
{
public:
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;
};
int main()
{
KlasaPochodna kp(5,4);
kp.Drukuj();
system("pause");
return 0;
}
Komentarz
•
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
•
4. 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(3)/4, 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 4 a) i b):
➢
Linia
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
Kod programu
#include <iostream>
#include <math.h>
using namespace std;
class Trojkat
{
private:
float x, y, z;
float obw2;
float pole;
public:
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);
Komentarz
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
private:
void ObliczObw2();
public:
float ObliczPole();
float ZwrocX();
// dokończyć samemu ZwrocY, ZwrocZ,
ZwrocPole, ZwrocObw2
void UstawPole(float _pole)
{
pole = _pole;
}
};
class TrojkatR : public Trojkat
{
public:
TrojkatR(float a) : Trojkat(a, a, a)
{ }
float ObliczPole()
{
float a = ZwrocX();
float p = a*a* sqrt(3.0)/4;
UstawPole(p);
return p;
}
};
int main()
{
Trojkat t1(3,2,3);
cout << "Pola trojkata wynosi: " <<
t1.ObliczPole() << endl;
TrojkatR t2(3);
cout << "Pole trojkata równobocznego
wynosi: " << t2.ObliczPole() << endl;
system("pause");
}
Trojkat::Trojkat()
{
x = y = z = obw2 = pole = 0;
}
Trojkat::Trojkat(Trojkat& t)
{
x = t.x;
y = t.y;
z = t.z;
obw2 = t.obw2;
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,
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
float _z)
{
if(SprawdzXYZ(_x, _y, _z))
{
x = _x;
y = _y;
z = _z;
}
}
void Trojkat::ObliczObw2()
{
obw2 = (x + y + z) / 2;
}
float Trojkat::ObliczPole()
{
ObliczObw2();
pole = sqrt(obw2*(obw2 - x) * (obw2 y) * (obw2 - z));
return pole;
}
float Trojkat::ZwrocX()
{
return x;
}

Podobne dokumenty