Laboratorium 4 - Kajetan Kurus

Transkrypt

Laboratorium 4 - Kajetan Kurus
Laboratorium 4 - dziedziczenie, klasy abstrakcyjne,
polimorfizm
mgr inż. Kajetan Kurus
25 marca 2014
1
Podstawy teoretyczne
1. Dziedziczenie
(a) dziedziczenie pól i metod
(b) przesłanianie funkcji
(c) widoczność elementów: public, private, protected
2. Polimorfizm
3. Funkcje wirtualne
4. Klasy abstrakcyjne
2
Zadanie do rozwiązania na zajęciach
2.1
Treść zadania
1. Należy stworzyć klasę pojazd, będącą ”‘ogólną klasą”’ reprezentującą wszystkie
możliwe pojazdy kołowe. Klasa pojazd ma zawierać konstruktor parametryczny
i bezparametryczny, pole kola oraz metodę dodajKola z jednym parametrem.
Następnie należy stworzyć dwie klasy (osobowy i quad ) dziedziczące po klasie
pojazd. Do klasy osobowy należy dodać pole osoby oraz metodę dodajOsoby .
Natomiast w klasę quad należy przesłonić metodę dodajKola aby dodawała tylko
wartość 4 ignorując argument wejściowy.
2. Sworzyc klasę abstrakcyjną jednostkaPlywajaca , która zawiera metody wirtualne
plyn, cumuj oraz predkosc. Następnie należy stworzyć dwie klasy dziedziczące
po jednostkaPlywajaca: jacht oraz tankowiec. Należy sprawdzić czy możliwe jest
stworzenie obiektu klasy jednostkaPlywajaca oraz jacht, gdy nie wszystkie metody
z jednostkaPlywajaca są zaimplementowane.
1
2.2
Rozwiązanie zadania 1
Dziedziczenie po danej klasie umożliwia przejmowanie jej pól i metod widocznych jako
public i protected. Dzięki takiemu rozwiązaniu można tworzyć co raz bardziej wyspecjalizowane klasy bez potrzeby kopiowania/implementowania na nowo istniejących metod.
W przypadku, gdy w najwyższej klasie dokonamy modyfikacji lub dodamy nową funkcjonalność, nie będzie konieczności zmiany reszty klas.
Aby dziedziczyć po klasie należy podczas tworzenia klasy potomnej zawrzeć odniesienie
do klasy bazowej.
1
2
3
class
...
};
klasaPotomna
:
public klasaBazowa {
Dodanie parametru widoczności informuje kompilator jak mają być widoczne elementy
klasy bazowej.
public:
public → public
protected → protected
protected:
public → protected
protected → protected
private: lub brak operatora
public → private
protected → private
Należy pamiętać, że elementów private: z klasy bazowej nie można dziedziczyć. Czasami istnieje potrzeba zmiany dziedziczonej metody aby spełniała kryteria klasy potomnej.
Można tego dokonać przesłaniając konkretną funkcję. Polega to na re-deklaracji metody
wewnątrz nowej klasy i ponowne jej zdefiniowanie. Przykładem przesłaniania funkcji jest
klasa quad i jej metoda dodajKola.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#i n c l u d e <i o s t r e a m >
#i n c l u d e <s t r i n g >
u s i n g namespace s t d ;
c l a s s pojazd {
// K l a s a bazowa
public :
pojazd () ;
pojazd ( int k ) ;
void dodajKola ( i n t k ) ;
protected :
i n t kola ;
private :
string info ;
};
pojazd : : pojazd () {
kola = 0 ;
}
pojazd : : pojazd ( int k ){
kola = k ;
}
2
23
24
25
26
27
28
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
void pojazd : : dodajKola ( i n t k ) {
kola = k ;
c o u t << ” dodano k o l : ” <<k<<e n d l ;
}
c l a s s osobowy : public pojazd {
public :
osobowy ( int k , int o ) ;
void dodajOsobe ( i n t o ) ;
private :
int osoby ;
};
osobowy : : osobowy ( int k ,
kola = k ;
osoby = o ;
}
// K l a s a d z i e d z i c z a c a po k l a s i e p o j a z d
int o){
void osobowy : : dodajOsobe ( i n t o ) {
osoby = o ;
c o u t << ” dodano o s o b : ” << o <<e n d l ;
}
c l a s s quad : public pojazd {
public :
quad ( i n t k ) ;
void dodajKola ( i n t k ) ;
bazowej pojazd
};
// K l a s a d z i e d z i c z a c a po k l a s i e p o j a z d
// P r z e s l a n i a n i e metody d o d a j K o l a z k l a s y ←-
quad : : quad ( i n t k ) {
kola = k ;
}
void quad : : dodajKola ( i n t k ) {
kola = 4 ;
c o u t<<” quad moze miec t y l k o 4 k o l a ”<<e n d l ;
}
void main ( ) {
pojazd P ;
osobowy O (4 ,4) ;
quad Q (4) ;
P.
O.
O.
Q.
dodajKola (8) ;
dodajKola (4) ;
dodajOsobe (2) ;
dodajKola (5) ;
s y s t e m ( ”PAUSE” ) ;
}
Po uruchomieniu programu widać, że dla obiektów klasy pojazd i osobowy metoda dodajKola wyświetla komunikat o dodaniu nowej ilości kół. Natomiast dla obiektu klasy quad
wywołanie tej samej metody skutkuje wywołaniem jej własnej funkcji.
3
2.3
Rozwiązanie zadania 2
Klasa abstrakcyjna jest specyficzną formą klasy, która ma za zadanie wymuszać na klasach
dziedziczących własne implementacje podanych metod. Klasa czysto abstrakcyjna zawiera
w sobie tylko metody wirtualne dodatkowo zapisane wartością 0.
c l a s s abstrakcyjna {
v i r t u a l void metodaAbstrakcyjna () = 0;
};
1
2
3
Każda klasa dziedzicząca po klasie abstrakcyjnej ma obowiązek zaimplementować pewne
metody, w innym przypadku obiekty tej klasy nie będą mogły być utworzone.
1
2
3
4
5
6
7
8
9
10
11
12
#i n c l u d e <i o s t r e a m >
u s i n g namespace s t d ;
class jednostkaPlywajaca {
public :
v i r t u a l void plyn ( ) = 0 ;
v i r t u a l bool cumuj () = 0;
v i r t u a l void predkosc ( i n t v ) = 0;
};
// metoda w i r t u a l n a
// metoda w i r t u a l n a
// metoda w i r t u a l n a
tankowiec : public jednostkaPlywajaca {
// k l a s a
abstrakcyjnej
void plyn ( ) ;
// i m p l e m e n t a c j a
abstrakcyjnej
bool cumuj () ;
// i m p l e m e n t a c j a
abstrakcyjnej
void predkosc ( i n t v ) ;
// i m p l e m e n t a c j a
abstrakcyjnej
int speed ;
class
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
// d e k l a r a c j a k l a s y a b s t r a k c y j n e j
};
void tankowiec : : plyn ( ) {
c o u t<<” t a n k o w i e c p l y n i e ”<<e n d l ;
}
bool tankowiec : : cumuj () {
c o u t<<” t a n k o w i e c cumuje ”<<e n d l ;
return true ;
}
void tankowiec : : predkosc ( i n t v ) {
speed = v ;
}
4
d z i e d z i c z a c a po k l a s i e ←metody k l a s y ←metody k l a s y ←metody k l a s y ←-
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
c l a s s j a c h t : p u b l i c j e d n o s t k a P l y w a j a c a { // k l a s a d z i e d z i c z a c a po k l a s i e ←abstrakcyjnej
void plyn ( ) ;
// i m p l e m e n t a c j a metody k l a s y ←abstrakcyjnej
int speed ;
};
void jacht : : plyn ( ) {
c o u t<<” j a c h t p l y n i e ”<<e n d l ;
}
void main ( ) {
//
jednostkaPlywajaca P;
// K o m p i l a t o r n i e p o z w o l i s t w o r z y c o b i e k t u k l a s y ←abstrakcyjnej
tankowiec T ;
//
jacht J ;
// K o m p i l a t o r n i e p o z w o l i s t w o r z y c o b i e k t u j a c h t , ←poniwaz n i e z a i m p l e m e n t o w a l w s z y s t k i c h metod d z i e d z i c z o n y c h po ←jednostkaPlywajaca
s y s t e m ( ”PAUSE” ) ;
}
Powyższy program został zakomentowany w dwóch miejscach w celu poprawnej kompilacji. Obiekt klasy jednostkaPlywajaca nie może zostać stworzony, ponieważ jest to klasa
abstrakcyjna o czym informuje nas kompilator na obrazku poniżej.
Dla klasy jacht nie zostały zaimplementowane wszystkie metody z klasy wirtualnej przez
co jej obiekt również nie może zostać stworzony.
5
3
Zadania indywidualne
Termin oddania 01-04-2014
3.1
Ocena 3.0
ˆ Zadanie z laboratorium
ˆ Dopisać metodę jedz() i hamuj(), które zmodyfikują pole bool pojazdWRuchu
dla klasy pojazd
ˆ Sprawdzić działanie nowych metod dla obiektów klasy quad i osobowy
ˆ Stworzyć klasę sedan dziedzicząca po klasie osobowy i przesłonić metodę dodajOsobe (dowolne działanie)
3.2
Ocena 4.0
ˆ Zadanie z laboratorium
ˆ Zadanie na 3.0
ˆ Dopisać brakujące metody tak, aby można było stworzyć obiekt klasy jacht.
ˆ Stworzyć w klasie tankowiec metodę wirtualną zrzutPaliwa, która nie zrobi z niej
klasy abstrakcyjnej (należy zaimplementować metodę w klasie)
ˆ Stworzyć klasę superTankowiec dziedziczącą po klasie tankowiec i zaimplementować zrzutPaliwa .
ˆ Utworzyć w main obiekty każdej z klas i przetestować metody.
ˆ Przypisać do nowego obiektu tankowiec, wskaźnik do obiektu superTankowiec
a następnie wywołać metodę zrzutPaliwa (kod poniżej). W komentarzu opisać co
się stało.
1
2
3
4
5
6
7
tankowiec T ;
s u p e r t a n k o w i e c sT ;
T . zrzut () ;
sT . zrzut ( ) ;
t a n k o w i e c * wT ;
w T = &s T ; // z a m i s t &s t moze byc new s u p e r t a n k o w i e c ( ) ;
wT−>z r z u t ( ) ;
3.3
Ocena 5.0
ˆ Zadanie z laboratorium
ˆ Zadanie na 3.0
ˆ Zadanie na 4.0
6
ˆ Stworzyć klasę abstrakcyjną samolot zawierającą metody startuj(), ląduj(),
tankuj()
ˆ Stworzyć jedną klasę abstrakcyjną odrzutowiec dziedziczącą po samolot, dodającą
kolejne metody zwiekszCiag() i zmniejszCiag()
ˆ Stworzyć klasę smiglowy dziedziczącą po samolot zawierającą metodę wirtualną
zakrecSmiglem
ˆ Stworzyć klasę awionetka oraz herkules. Dla klasy herkules zaimplementować
nową metodę zakrecSmiglem . Analogicznie do ostatniego punktu oceny na 4.0,
do obiektu klasy smiglowy przypisać wskaźnik do awionetka i herkules. Wyniki
zapisać w komentrzu
ˆ Stworzyć klasę lightJet dziedziczący po klasie odrzutowiec.
7

Podobne dokumenty