Paradygmat programowania obiektowego klasa obiekt Paradygmat sownik PWN
Paradygmat programowania obiektowego, klasa, obiekt
Paradygmat (słownik PWN) przyjęty sposób widzenia rzeczywistości w danej dziedzinie • Paradygmaty imperatywne i deklaratywne • Popularne paradygmaty programowania – programowanie strukturalne – programowanie proceduralne – programowanie obiektowe
Paradygmat programowania obiektowego Programowanie obiektowe (ang. : object oriented programming, OOP) • to paradygmat rozwiązywania problemów programistycznych z wykorzystaniem obiektów, które dla programu reprezentują zarówno stan jak i zachowanie rzeczywistych obiektów fizycznych (lub abstrakcyjnych) • to sposób interpretacji problemu jako zbioru obiektów i relacji pomiędzy nimi.
Obiekt • Potoczne znaczenie słowa obiekt – intuicyjnie wiemy. . . – może być nazwany, zazwyczaj opisywany rzeczownikiem –. . . • Znaczenie pojęcia obiektu w programowaniu – Reprezentuje na potrzeby programu obiekty (w potocznym znaczeniu słowa obiekt) ze świata rzeczywistego (tzw. dziedziny problemowej) lub abstrakcyjne – Uogólniona zmienna (struktura) – Zdefiniowany i używany zgodnie ze składnią i semantyką języka programowania
Obiekt - uogólniona zmienna (struktura) • Struktura – zestaw danych, najczęściej różnych typów • reprezentuje stan obiektu z dziedziny problemowej • Uogólniona – obiekt = dane + metody operujące na tych danych • reprezentuje stan oraz sposób zachowania się obiektu z dziedziny problemowej
Dużo obiektów • 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 • Potrzebujemy klasy dla podobnych obiektów
Klasa w programowaniu • Klasa w programowaniu — uogólniony typ zdefiniowany przez użytkownika języka • 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
Dlaczego programowanie obiektowe? • kolejny etap w rozwoju technik IP: – strukturalne – proceduralne – modularne • narzędzie do implementacji projektów obiektowych (istneje analiza obiektowa, projektowanie obiektowe) – języki wspierające programowanie obiektowe • C++, C#, Java, … – języki umożliwiające programowanie obiektowe • wszystkie (przynajmniej wszystkie impreatywne ogólnego przeznaczenia)
Przykład – osoba strukturalnie struct person { int age; char FName[20], LName[30]; }; void person_input(person *o); void person_set(person *o, int age, char *p. FN, char *p. LN); void person_output(person *o); • • 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 person { int age; // składowe klasy – zmienne klasowe string FName, LName; // lub: atrybuty klasy public: void input(); // składowe klasy – metody klasy void output(); // lub: funkcje klasowe void set(int age, const string& FN, const string& p. LN); }; • • • // deklarację klasy kończymy średnikiem dane i metody razem domyślnie bez dostępu do pól spoza metod klasy łatwiej posługiwać się obiektowym typem string niż strukturalnym char*
Specyfikacja dostępu do składowych klasy private: składowe prywatne dostępne dla metod danej klasy oraz metod i funkcji zaprzyjaźnionych private – domyślne dla „class” public: składowe publiczne dostępne spoza klasy domyślne dla „struct” protected: składowe chronione tak jak private, ale mogą być dodatkowo dostępne dla klas potomnych
Specyfikacja dostępu do składowych klasy class person { int age; string FName; // private public: void input(); // public private: string LName; // private public: void output(); // public void set(int, const string&); }; // public
Enkapsulacja Zamknięcie danych i metod w klasie pozwala programiście na świadome ograniczenie możliwości dostępu do danych przez kod spoza klasy (co jest/było czasem określane mianem hermetyzacji). • 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. Jest użyteczne, np dla zrównoleglania kodu.
Obiekt: uogólniona struktura • Deklarujemy class person me, you; person boss; // w deklaracji/definicji obiektu można // pomijać „class”, „struct” i „union” • Używamy boss. input(); boss. output();
Operatory dostępu do składowych klasy • kropka „. ” obiekt. zmienna; obiekt. metoda(); // jak w strukturach C // enkapsulacja • operator zakresu „ : : „ klasa: : zmienna; klasa: : metoda(); // sizeof, pola static // przy definicji, metody statyczne • Najczęściej kwalifikacje (obiekt. i klasa: : ) można pominąć – metody klasy operujące na nieprzesłoniętych składowych klasy – deklarowanie/definiowanie metod wewnątrz deklaracji klasy
Jak definiować metody klasy? • Wewnątrz deklaracji klasy class person { //. . . void input() { cin >> age >> FName >> LName; } // tu nie musi być średnika //. . . }; • Taka metoda jest domyślnie metodą inline
Jak definiować metody klasy? • poza klasą – trzeba użyć operatora zakresu w nagłówku – domyślnie metoda nie będzie inline void person: : set(int age, const string& p_FName, const string& p_LName) { person: : age = age; // tu również operator zakresu // bo wiek przysłonięty FName = p_FName; LName = p_LName; } • metoda ma być inline? inline void person: : output() { cout << "age: " << age << " name: " << FName << " last name: " << LName << "n"; }
Jak definiować metody klasy? • przy tworzeniu bibliotek w pliku nagłówkowym (*. h) umieszczamy deklaracje klasy i definicje metod inline, pozostałe metody w *. cpp. • metody podobnie jak funkcje mogą mieć argumenty domyślne i być przeciążane void set(int age, const string& = "John", const string& = "Kowalski"); void set(const person& other); boss. set(you); boss. set(50, "Tom", "Smith"); boss. set(50, "Tom"); boss. set(50); // boss. set(); ERROR!
Jak definiować metody klasy? • metody i zmienne zadeklarowane wewnątrz klasy są widoczne od początku definicji klasy oraz wewnątrz ciał metod zadeklarowanych wewnątrz klasy • nawet gdy definicja metody znajduje się poza klasą • zaleca się najpierw deklarować zmienne, następnie metody. class A { public: void input() { cin >> i; // deklaracja „i” jest w klasie output(); // jak wyżej } void output(); int i; };
Jak definiować metody klasy? • Przypomnienie: spoza 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: : input; a. i = 3; // i jest publiczne w A }
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(); } // // C: : i++ global i C: : fun() global fun()
Przykład zadanie • zadeklarować klasę point, której obiekty będą punktami na płaszczyźnie 2 D – klasa powinna nie mieć zmiennych publicznych – publiczne inline metody klasy: • input, output, • move (przesuń o wektor zadany parą współrzędnych), • distance (odległość od drugiego punktu przekazanego przez referencję) • coord. X i coord. Y zwracające rzędną i odciętą punktu (tzw. akcesory)
Przykład class point { double x, y; public: void input(); void output(); void move(double dx, double dy); double distance(const punkt &p); double coord. X(); double coord. Y(); };
Przykład zadanie • zdefiniować inline metody klasy point class point { double x, y; public: void input() { cin >> x >> y; }; void output() { cout << x << ' ' << y; }; void move(double dx, double dy); double distance(const punkt &p); double coord. X() { return x; }; double coord. Y() { return y; }; };
Przykład inline void point: : move(double dx, double dy) { x += dx; y += dy; } inline double point: : distance(point &p) { return sqrt((x - p. x)*(x - p. x) + (y - p. y)*(y - p. y)); } • uwaga: mamy dostęp do prywatnych pól wszystkich obiektów klasy obiektu na którego rzecz aktywowana jest metoda. Prywatne znaczy prywatne dla klasy (a nie dla obiektu klasy).
Klasy a Abstrakcyjne Typy Danych • klasy doskonale nadają się do implementacji abstrakcyjnych typów danych. . . gdyż. . . • klasy są abstrakcyjnymi typami danych • Znamy interfejs – gdy posługujemy się operacjami dozwolonymi dla typu, nie przejmujemy się tym, jak są one realizowane. – Enkapsulacja pozwala oddzielić nieistotne z punktu widzenia użytkownika typu szczegóły implementacyjne od istotnego interfejsu. • na przykład stos, kolejka, zbiór, punkt, odcinek
Przykład zadanie cd. • zadeklarować klasę segment, której obiekty będą odcinkami na płaszczyźnie 2 D – klasa powinna nie mieć zmiennych publicznych – publiczne metody klasy: input, output, – move (przesuń o wektor zadany parą współrzędnych), – length (wyznacz długość odcinka).
Przykład class segment { point p 1, p 2; public: void input() { p 1. input(); p 2. input(); } void output() { p 1. output(); cout << ' '; p 2. output(); } void move(double dx, double dy) { p 1. move(dx, dy); p 2. move(dx, dy); } double length() { return p 1. distance(p 2); } };
Zagnieżdżone deklaracje klas • deklaracja klasy może być zagnieżdżona w deklaracji innej klasy • klasa zagnieżdżona nie jest widoczna globalnie class X { public: class M 2 { int m; }; }
Zagnieżdżone deklaracje klas class X { class M 1 { int m; }; public: class M 2 { int m; }; } void f() { M 1 m 1; // error, M 1 // not in global scope X: : M 1 xm 1; // error, M 1 is // a private class in X X: : M 2 xm 2; // OK } • X to klasa która nie ma żadnych zmiennych ani metod, tylko określone typy (można oczywiście tworzyć obiekty klasy X).
- Slides: 30