Programowanie obiektowe w C++
Transkrypt
Programowanie obiektowe w C++
Programowanie obiektowe w C++ dr inż. Tadeusz Wilusz Akademia Ekonomiczna w Krakowie 31-510 Kraków, ul. Rakowicka 27 Budynek Biblioteki Głównej pokój 429 tel.: 2935-264 e-mail: [email protected] Programowanie obiektowe w C++ Wykład 02 Temat wiodący: Koncepcja klasy. Obiekty. 1 Plan wykładu n n n Wprowadzenie Rozszerzenia nieobiektowe Paradygmat obiektowy, klasa Paradygmat programowania obiektowego, klasa, obiekt 2 Paradygmat paradygmat (słownik PWN) — przyjęty sposób widzenia rzeczywistości w danej dziedzinie n Paradygmaty programowania n n programowanie strukturalne programowanie obiektowo zorientowane (obiektowe) Paradygmat programowania obiektowego programowanie obiektowe — to paradygmat rozwiązywania problemów programistycznych z wykorzystaniem obiektów, sposób interpretacji problemu jako zbioru obiektów i relacji pomiędzy nimi. 3 Obiekt n n Potoczne znaczenie słowa obiekt Znaczenie pojęcia obiektu w programowaniu n n n Reprezentuje na potrzeby programu obiekty ze świata rzeczywistego lub abstrakcyjne (w potocznym znaczeniu słowa obiekt) Uogólniona zmienna (struktura) Zdefiniowany i używany zgodnie ze składnią i semantyką języka Obiekt - uogólniona zmienna (struktura) n Struktura n n zestaw danych, najczęściej różnych typów Uogólniona n obiekt = dane + metody operujące na tych danych 4 Obiekt - przykałady Dużo obiektów n zazwyczaj wiele obiektów ma taki sam zbiór cech, potrzebujemy aby te cechy definiować raz, ale wykorzystywać wielokrotnie klasa (słownik PWN) — kategoria przedmiotów lub zjawisk wyróżnionych na podstawie wspólnych cech n Potrzebujemy klasy dla podobnych obiektów 5 Klasa w programowaniu n klasa w programowaniu — uogólniony typ zdefiniowany przez użytkownika języka n służy do definiowania obiektów (uogólnionych zmiennych) Dostarcza wielu nowych możliwości (to be discussed later :-) Pojedyncza klasa powinna jasno reprezentować określone pojęcie, dla którego nie istnieje (jeszcze) odpowiedni typ n n Dlaczego programowanie obiektowe? n kolejny etap w rozwoju technik IP: n n n n strukturalne proceduralne modularne narzędzie do implementacji projektów obiektowych (istneje analiza obiektowa, projektowanie obiektowe) n n języki wspierające programowanie obiektowe C++, Java, … kęzyki umożliwiające programowanie obiektowe wszystkie 6 Przykład – osoba strukturalnie struct osoba { int wiek; char imię[20], nazwisko[30]; }; void wczytaj_osobe(osoba *o); void ustaw_osobę(osoba *o, int wiek, char *imię, char *nazwisko); void wypisz_osobe(osoba *o); n n bez kontroli dostępu do pól struktury programista musi pamiętać, których funkcji używać na rzecz których struktur Przykład – osoba obiektowo class osoba { int wiek; // składowe klasy – zmienne klasowe char imię[20], nazwisko[30]; public: void wczytaj(); // składowe klasy – metody klasy void ustaw(int wiek, char *p_imię, char *p_nazwisko); void wypisz(); }; // ten średnik musi tu być by zakończyć deklarację n n dane i metody razem domyślnie bez dostępu do pól spoza metod klasy 7 Specyfikacja dostępu do składowych klasy n private: // składowe prywatne // dostępne dla metod danej klasy // oraz metod i funkcji zaprzyjaźnionych // private – domyślne dla „class” n public: // składowe publiczne // dostępne spoza klasy // domyślne dla „struct” n protected: // składowe chronione // tak jak private, ale // mogą być dodatkowo dostępne dla klas potomnych Specyfikacja dostępu do składowych klasy class osoba { int wiek; // private char imię[20]; // private public: void wczytaj(); // public private: char nazwisko[30]; // private public: void ustaw(int wiek, char *p_imię, char *p_nazwisko); void wypisz(); // public }; // public 8 Hermetyzacja i enkapsulacja Zamknięcie danych i metod w klasie (enkapsulacja) pozwala programiście na świadome ograniczenie możliwości dostępu do danych przez kod spoza klasy (hermetyzacja). n n Domyślnie wszystkie składowe klasy są prywatne, czyli niedostępne z zewnątrz klasy. OOOP ;-) — ortodoksyjne programowanie obiektowe: wszystkie dane są prywatne, operujemy na nich wyłącznie metodami klasy. Obiekt – uogólniona struktura n Deklarujemy class osoba ja, Ty; osoba szef; // w deklaracji/definicji obiektu można // pomijać „class”, „struct” i „union” n Używamy szef.wczytaj(); szef.wypisz(); 9 Operatory dostępu do składowych klasy n kropka „ . ” obiekt.pole; obiekt.metoda(); n operator zakresu „ :: „ klasa::pole; klasa::metoda(); n // jak w strukturach C // enkapsulacja // sizeof, pola static // przy definicji, metody statyczne Najczęściej kwalifikacje ( obiekt. i klasa::) można pominąć n n metody klasy operujące na nieprzesłoniętych składowych klasy deklarowanie/definiowanie metod wewnątrz deklaracji klasy Jak definiować metody klasy? n Wewnątrz deklaracji klasy class osoba { … void wczytaj() { cin>>wiek>>imie>>nazwisko; } // tu nie musi być średnika … }; n Taka metoda jest domyślnie metodą inline 10 Jak definiować metody klasy? n n poza klasą trzeba użyć operatora zakresu w nagłówku domyślnie metoda nie będzie inline void osoba::ustaw(int wiek, char *p_imię, char *p_nazwisko) { osoba::wiek=wiek; // tu też operator zakresu bo wiek przysłonięty strcpy(imię, p_imię); strcpy(nazwisko, p_nazwisko); } n metoda ma być inline? inline void osoba::wypisz() { cout<<"wiek: "<<wiek<<" imie: "<<imie<<" nazwisko: "<<nazwisko<<"\n"; } Jak definiować metody klasy? n przy tworzeniu bibliotek w pliku nagłówkowym (*.h) umieszczamy deklaracje klasy i definicje metod inline, definicje nie-inline nie mogą znaleźć się w *.h. n metody podobnie jak funkcje mogą mieć argumenty domyślne i być przeciążane void ustaw(int w, char *pi="Jan", char *pn="Kowalski"); void ustaw(const osoba & przyklad); szef.ustaw(Ty); szef.ustaw(50, „Osama”, „bin Laden”); szef.ustaw(50, „Osama”); szef.ustaw(50); // szef.ustaw(); ERROR! 11 Jak definiować metody klasy? n metody i zmienne zadeklarowane wewnątrz klasy są widoczne od początku definicji klasy oraz wewnątrz ciał metod zadeklarowanych wewnątrz klasy class A { public: void wczytaj() { cin>>i; // deklaracja „i” jest w klasie wypisz(); // jak wyżej } void wypisz(); int i; }; Jak definiować metody klasy? n Przypomnienie: z poza metod klasy jej składowe trzeba kwalifikować nazwą klasy bądź obiektu int test() { A a; int j=sizeof(A::i); void (A::*p)()=&A::wczytaj; a.i=3; // i jest publiczne w A } 12 Operator zakresu jako rozszerzenie nieobiektowe int fun(); int i; class C { int i; public: void test(); int fun(); }; void C::test() { i++; ::i++; fun(); ::fun(); } // zwieksz C::i // globalne i // C::fun() // globalna fun() Przykład zadanie n zadeklarować klasę point, której obiekty będą punktami na płaszczyźnie 2D n n klasa powinna nie mieć zmiennych publicznych publiczne metody klasy: input, output, move (przesuń o wektor zadany parą współrzędnych), distance (odległość od drugiego punktu przekazanego przez referencję) oraz metody coordX i coordY zwracające rzędną i odciętą punktu 13 Przykład class point { double x, y; public: void input(); void output(); void move(double dx, double dy); double distance(const punkt &p); double coordX(); // tzw akcesory – udostępniają prywatne pola klasy double coordY(); }; Przykład zadanie n zdefiniować inline metody n input() n output() n move() n distance() 14 Przykład class point { double x, y; public: void input() {cin>>x>>y; }; void output() {cout<<x<<y; }; … }; inline void point::move(double dx, double dy) { x+=dx; y+=dy; } Przykład inline double point::distance(point &p) { return sqrt( (x-p.x)*(x-p.x) + (y-p.y)*(y-p.y) ); } n uwaga: mamy dostęp do prywatnych pól obiektu na rzecz którego aktywowana jest dana metoda i do prywatnych pól innych obiektów klasy tej co obiektu na którego rzecz aktywowana jest metoda (p). Prywatne znaczy prywatne dla klasy (a nie dla obiektu klasy). 15 Klasy a Abstrakcyjne Typy Danych n n klasy doskonale nadają się do implementacji abstrakcyjnych typów danych klasy są abstrakcyjnymi typami danych n Znamy interfejs – gdy posługujemy się operacjami dozwolonymi dla typu, nie przejmujemy się tym, jak są one realizowane. Hermetyzacja pozwala oddzielić nieistotne z punktu widzenia użytkownika typu szczegóły implementacyjne od istotnego interfejsu. n na przykład stos, kolejka, zbiór, punkt, odcinek Przykład zadanie n zadeklarować klasę segment, której obiekty będą odcinkami na płaszczyźnie 2D n n klasa powinna nie mieć zmiennych publicznych publiczne metody klasy: input, output, move (przesuń o wektor zadany parą współrzędnych), length (długość odcinka). 16 Przykład class segment { point p1, p2; public: void input() { p1.input(); p2.input(); } void output() { p1.output(); p2.output(); } void move(double dx, double dy) { p1. move(dx, dy); p2. move(dx, dy); } double length() { return p1.distance(p2); } }; Ciekawostka: deklaracje zagnieżdżone n n deklaracja klasy może być zagnieżdżona w deklaracji innej klasy klasa zagnieżdżona nie jest widoczna globalnie, można kwalifikować klasą zewnętrzną jeżeli jest publiczna. 17 Ciekawostka: deklaracje zagnieżdżone void f() { M1 m1; // blad //nie w zasięgu globalnym class X { class M1 { int m; X::M1 xm1; // blad //M1 w sekcji prywatnej X }; public: class M2 { X::M2 xm2; int m; // ok. } }; }; Ciekawostka: deklaracje zagnieżdżone n X to klasa która nie ma żadnych zmiennych ani metod, tylko określone typy (można oczywiście tworzyć obiekty klasy X). klasa, która zawiera zmienne klasowe: class X_d { public: class M2 { int m; }; M2 m2; // tutaj }; n generalnie należy unikać i unika się zagnieżdżania klas (za wyjątkiem bardzo małych klas) — mało czytelne i mało przydatne. 18