310 likes | 589 Views
Zachodniopomorska Szkoła Biznesu. Podstawy programowania II. Wykład 6: Programowanie obiektowe - Klasy i obiekty. Programowanie obiektowe. Podstawowymi elementami języka obiektowego są:
E N D
Zachodniopomorska Szkoła Biznesu Podstawy programowania II Wykład 6: Programowanie obiektowe - Klasy i obiekty
Programowanie obiektowe • Podstawowymi elementami języka obiektowego są: • KlasaOpis formalny zestawu danych oraz operacji, jakie można wykonać na tych danych.Klasa definiuje więc sposób obsługi danych w niej zawartych. • Obiektkonkretny egzemplarz danej klasy Obiekt: v1 Dane: x=10 y=-3 Klasa: wektor Dane:- x- y Działania: - Wypisz współrzędne- Oblicz długość Obiekt: v2 Dane: x=0 y=5 Podstawy programowania - Programowanie obiektowe - klasy i obiekty
Cechy programowania obiektowego • EnkapsulacjaUkrywanie wewnątrz klasy mechanizmów jej działania, pozostawienie dostępu jedynie do tych składników, które pozwalają z niej korzystać • Zawieranie się klas wewnątrz innych • Dziedziczenie Tworzenie klas na bazie innych klas, można je rozumieć jako utworzenie podklasy • PolimorfizmIstota "orientowania obiektowego", związana ściśle z dziedziczeniem. Automatyczny wybór działania klasy w zależności od podklasy, do której należy dany obiekt • Podobieństwo do ludzkiego postrzegania rzeczywistości • Duża efektywność tworzenia złożonych systemów • Specyficzne podejście przy projektowaniu Podstawy programowania - Programowanie obiektowe - klasy i obiekty
Języki obiektowe • SmallTALK (pierwowzór) • C++, C# • Obiektowe wersje języków proceduralnych: • Pascal (później Delphi) • Ada • BASIC • LISP • Python, Perl • Java Podstawy programowania - Programowanie obiektowe - klasy i obiekty
Klasy • Klasa jest abstrakcją, która pozwala na zdefiniowanie struktury i zachowania danego obiektu. W związku z tym zawiera: • Właściwości (dane składowe) • prywatne (dostępne tylko dla tej klasy) • publiczne (dostępne z zewnątrz) • Metody (funkcje składowe) • prywatne • publiczne • Użycie klasy polega na utworzeniu obiektu (obiektów) o typie określonym nazwą klasy, a następnie korzystaniu z tych jego właściwości i metod, które są dostępne na zewnątrz (publiczne). • Klasy są bardzo podobne do rekordów (struktur), różnią się tylko tym, że obok danych definiują również metody Podstawy programowania - Programowanie obiektowe - klasy i obiekty
Klasy w C++: typ class • Składnia: class NazwaKlasy { [ public: lub protected: lub private:] deklaracje zmiennych - właściwości deklaracje/definicje funkcji - metod }; • Kolejność deklaracji nie ma znaczenia • Tryb dostępu można zmieniać wielokrotnie • Podany tryb dostępu dotyczy wszystkich kolejnych deklaracji aż do zdefiniowania innego trybu • Domyślny tryb dostępu to private! Podstawy programowania - Programowanie obiektowe - klasy i obiekty
Przykłady deklaracji klasy class osoba // klasa bez metod{ public: char nazwisko[30]; char telefon[20];}; class wektor{ float x,y; // x i y są private! public: float dlugosc() // metoda { return sqrt(x*x+y*y); } }; Podstawy programowania - Programowanie obiektowe - klasy i obiekty
Utworzenie obiektu danej klasy • Nazwę klasy można rozumieć jako nazwę nowego typu danych. Utworzenie obiektu odbywa się jako utworzenie zmiennej o tym typie, czyli: NazwaKlasy NazwaZmiennej; NazwaKlasy *Wskaznik = new NazwaKlasy; • Dostęp do składników klasy odbywa się poprzez operatory. lub -> NazwaZmiennej.DanaSkładowa NazwaZmiennej.FunkcjaSkładowa(parametry) Wskaznik->DanaSkładowa Wskaznik->FunkcjaSkładowa(parametry) Przykład: CLASS.CPP Podstawy programowania - Programowanie obiektowe - klasy i obiekty
Utworzenie tablicy obiektów • Tablica obiektów działa tak samo, jak tablica rekordów: NazwaKlasy NazwaTablicy[LiczbaObiektów]; • Dostęp do konkretnych danych lub funkcji składowych: NazwaTablicy[IndeksObiektu].DanaNazwaTablicy[IndeksObiektu].Funkcja(parametry) • Przykład class Wektor { // deklaracja klasy public: float x, y; // dane void wypisz() { // metoda { cout << "[ " << x << ", " << y << "]"; }};... Wektor tab[10]; // utworzenie tablicy tab[0].x=2; // dostęp do danych tab[0].y=5; tab[0].wypisz(); // dostęp do metody Przykład: TABCLASS.CPP Podstawy programowania - Programowanie obiektowe - klasy i obiekty
Obiekt będący składnikiem klasy Lampa Zarowka: zarowka kolor jasnosc kolor_klosza • Zawieranie klas wewnątrz innych:Składnikiem klasy może być obiekt innej klasy . Tego typu sytuacja zachodzi, gdy coś jest częścią czegoś innego. Pozwala to opisać bardzo złożone obiekty poprzez ich części składowe class Zarowka{ int kolor, jasnosc;}; class Lampa{ Zarowka zarowka; int kolor_klosza}; Podstawy programowania - Programowanie obiektowe - klasy i obiekty
Obiekt będący składnikiem klasy Samochod Lampa: PrzedniaP Lampa: PrzedniaL Zarowka: zarowka Zarowka: zarowka kolor jasnosc kolor jasnosc kolor_klosza kolor_klosza Lampa: TylnaP Lampa: TylnaL Zarowka: zarowka Zarowka: zarowka kolor jasnosc kolor jasnosc kolor_klosza kolor_klosza • Zawieranie się obiektów może być wielopoziomowe: class Zarowka { int kolor, jasnosc;}; class Lampa { Zarowka zarowka; int kolor_klosza}; class Samochod { // między innymi: Lampa PrzedniaP;Lampa PrzedniaL;Lampa TylnaP, TylnaL; };Przykład: LAMPY.CPP Podstawy programowania - Programowanie obiektowe - klasy i obiekty
Dostęp do składników klasy • Dostęp do składników klasy może zostać ograniczony w celu ukrycia części danych lub metod. Kontrolę dostępu zapewniają etykiety: • Public: - dla wszystkich • Private: - wyłącznie dla metod tej klasy • Protected: - dla metod tej klasy oraz klas od niej dziedziczących (wyjaśnienie w następnym wykładzie) • Próba dostępu do niedostępnego składnika powoduje błąd kompilacji • Domyślnym trybem dostępu jest Private !!! • Enkapsulacja - zamknięcie wewnątrz obiektu elementów i mechanizmów, do których dostęp z zewnątrz byłby niepotrzebny lub niebezpieczny Podstawy programowania - Programowanie obiektowe - klasy i obiekty
Dostęp do składników klasy (2) • Jeżeli chcemy pozwolić na dostęp do prywatnego składnika, można utworzyć w tym celu funkcje publiczne, np. class plotkarz { int sekret; // ukryta dana składowa (private) public: int powiedz_prosze() // funkcja odczytująca ... { return sekret; } void powiem_ci_sekret(int wiadomosc) // i zapisująca { sekret=wiadomosc; } }; Podstawy programowania - Programowanie obiektowe - klasy i obiekty
Typ struct • Typ ten pozostał w C++ z języka C, gdzie służył do definiowania struktury danych zwanej rekordem • Dzięki istnieniu typu struct programy napisane w C z użyciem rekordów kompilują się w C++ • W C++ poszerzono jednak możliwości tego typu, zrównując go prawie całkowicie z typem class • Jedyna różnica polega na tym, że dane i funkcje składowe w typie structsą domyślnie klasypublic • Przykład struct punkt3D{ float x, y, z; // dane publiczne// publiczna metoda: void ustaw(float xx, float yy, float zz) { x=xx; y=yy; z=zz; }}; Podstawy programowania - Programowanie obiektowe - klasy i obiekty
Deklaracje i definicje funkcji • Deklaracja - opis typu pewnego symbolu niezbędny kompilatorowi do kontroli jego użycia, np. nagłówek funkcji: int funkcja(float a, float b); • Definicja - pełny opis struktury i funkcjonowania tego symbolu, np. „ciało” funkcji int funkcja(float a, float b) { return a>b; } Podstawy programowania - Programowanie obiektowe - klasy i obiekty
Deklaracje i definicje metod w klasie • W deklaracji klasy nie musimy podawać pełnej definicji funkcji (metody), wystarczy podać jej prototyp - nagłówek, np.: class Prostokat{ float a,b; // dane float pole() // pełna definicja metody{ return a*b; } float obwod(); // tylko deklaracja metody }; • Definicja (ciało) funkcji musi się wtedy znaleźć w innym miejscu programu, konieczne jest jednak wtedy podanie nazwy klasy, do której funkcja należy i użycie operatora zakresu (::)float Prostokat::obwod() // definicja metody{ return 2*a + 2*b; } Podstawy programowania - Programowanie obiektowe - klasy i obiekty
Deklaracje i definicje metod (2) • Dobrą praktyką jest umieszczanie w opisie klasy tylko nagłówków funkcji za wyjątkiem bardzo krótkich (kilka linijek) funkcji, co zwiększa czytelność opisu klasy. Uwaga! Funkcje umieszczone w deklaracji klasy zostaną skompilowane jako inline! • W większych programach często definicja każdej klasy(np. MojaKlasa), zawierająca jedynie deklaracje funkcji składowych umieszczana jest w pliku nagłówkowym .H(np. MOJAKLASA.H), natomiast rozwinięcia funkcji składowych umieszczane są w odpowiadającym mu nazwą pliku .CPP(np. MOJAKLASA.CPP) Przykład: STRING100.CPP Podstawy programowania - Programowanie obiektowe - klasy i obiekty
Konstruktor • Funkcja uruchamiana w chwili powoływania obiektu do życia • Zazwyczaj ma na celu inicjalizację danych składowych(nie jest to możliwe w definicji klasy) • Nazwa konstruktora musi być identyczna z nazwą klasy • Konstruktor zawsze jest typu void • Konstruktor bez parametrów nazywa się domniemanym lub domyślnym • Jeżeli konstruktor posiada parametry wywołania - muszą być one przekazane podczas tworzenia obiektu Przykład: KONSTRUKTORY.CPP Podstawy programowania - Programowanie obiektowe - klasy i obiekty
Przeciążanie nazw funkcji • Własność wprowadzona w C++ (nie było jej w C) • Wolno zdefiniować w obrębie tego samego zakresu kilka funkcji o jednakowych nazwach pod warunkiem, że różnią się zestawem parametrów, np.: int a();int a(float x, float y);int a(int n); • Wybór właściwej funkcji do wykonania odbywa się na podstawie typów podanych parametrów,np. x = 2 * a(2); // trzecia z deklaracjix= a(); // pierwsza z deklaracjix = a(1,2.0); // druga z deklaracji Przykład: PRZECIAZANIE.CPP Podstawy programowania - Programowanie obiektowe - klasy i obiekty
Przeciążanie nazw funkcji składowych • Funkcje składowe klasy mogą być przeciążane tak samo jak zwykłe funkcje • Najczęściej przeciążaną funkcją jest konstruktor • Klasa może więc mieć kilka konstruktorów, ale podczas tworzenia obiektu użyć można tylko jednego z nich.O wyborze decydujemy poprzez zestaw parametrów podanych przy definicji obiektu. Przykład: ZESPOLONA.CPP Podstawy programowania - Programowanie obiektowe - klasy i obiekty
Destruktor • Funkcja uruchamiana w chwili zakończenia czasu życia obiektu (koniec programu lub funkcji albo zwolnienie pamięci pobranej dynamicznie na obiekt) • Nazwa destruktora to nazwa klasy poprzedzona znakiem ~ • Destruktor jest zawsze bezparametrową funkcją typu void, może być tylko jeden w klasie • Celem destruktora jest zwykle „posprzątanie” po obiekcie, w szczególności: • Zwolnienie pamięci pobranej dynamicznie przez obiekt • Zamknięcie plików otwartych przez obiekt Przykłady: DESTRUKTORY.CPP KONST-DEST.CPP Podstawy programowania - Programowanie obiektowe - klasy i obiekty
Składnik statyczny • Składnik o wartości wspólnej dla wszystkich obiektów klasy. Każdy obiekt tej klasy ma do niego dostęp. • Tworzony jest i inicjalizowany podobnie jak typowa zmienna globalna class Klasa { static int licznik; // liczba obiektów klasy Klasa() { licznik++; } int ile_obiektow() { return licznik; } }; int Klasa::licznik=0; Przykład: STATYCZNY.CPP Podstawy programowania - Programowanie obiektowe - klasy i obiekty
Lista inicjalizacyjna konstruktora (1) • Typowym zadaniem konstruktora jest nadanie wartości początkowej danym składowym (inicjalizacja), np.:class Wektor{ public: float x,y, suma; Wektor() // Konstruktor domniemany { x=0; y=0; suma=0; } Wektor (float X, float Y) { x=X; y=Y; suma=X+Y; } }; Podstawy programowania - Programowanie obiektowe - klasy i obiekty
Lista inicjalizacyjna konstruktora (1) • Istnieje uproszczona formuła dokonywania inicjalizacji, zwana listą inicjalizacyjną konstruktora, np.:class Wektor{ public: float x,y, suma; Wektor() // Konstruktor domniemany: x(0), y(0), suma(0) { } Wektor (float X, float Y): x(X), y(Y), suma(X+Y) { } }; Podstawy programowania - Programowanie obiektowe - klasy i obiekty
Konstruktory składników klasy (1) • Jeżeli klasa posiada składniki, które są obiektami innych klas, podczas tworzenia obiektu może zaistnieć konieczność uruchomienia konstruktorów tych składników • Nie jest to konieczne jeżeli klasy składników nie posiadają konstruktorów lub posiadają konstruktory domniemane • W przeciwnym wypadku, klasa nadrzędna musi mieć konstruktor • Wywołanie konstruktorów obiektów składowych umieszcza się wtedy na liście inicjalizacyjnej konstruktora Podstawy programowania - Programowanie obiektowe - klasy i obiekty
Konstruktory składników klasy (2) • Przykład class Punkt{ public: float x,y; Punkt(float X, float Y) : x(X), y(Y) { } // konstruktor}; // brak konstruktora domniemanegoclass Wektor{ public: Punkt p1, p2; // składniki - obiekty// konstruktor jest konieczny! Wektor (Punkt P1, Punkt P2) : p1(P1.x, P1.y), p2(P2.x, P2.y)//musi być! { } }; Przykład: LISTA_INIT.CPP Podstawy programowania - Programowanie obiektowe - klasy i obiekty
Konstruktor kopiujący (1) • Jest to specjalny konstruktor, który rusza do pracy wtedy, gdy chcemy zainicjować nowy obiekt kopiując jego zawartość z innego obiektu, np.:Klasa wzorzec;Klasa kopia=wzorzec; // inicjalizacja • Druga sytuacja występuje, gdy podajemy obiekt jako parametr funkcji, np.:void funkcja (Klasa kopia) // funkcja{ ... } // wywołanie:Klasa wzorzec;funkcja (wzorzec); • Domyślnie kopiowane są zawsze wszystkie składniki, ale nie zawsze tak chcemy!Jeżeli trzeba to zmienić, potrzebny jest konstruktor kopiujący. Podstawy programowania - Programowanie obiektowe - klasy i obiekty
Konstruktor kopiujący (2) • Deklaracja:class Klasa{ ... Klasa (Klasa &wzorzec); // referencja do Klasy ...}; • Przykład:class Punkt{ public: float x, y, nr_kopii; Klasa (Klasa &wzorzec) { x=wzorzec.x; y=wzorzec.y; nr_kopii=wzorzec.nr_kopii+1; }};Przykład: KOPIUJACY.CPP Podstawy programowania - Programowanie obiektowe - klasy i obiekty
Wskaźnik na klasę, wskaźnik this • Wskaźnik na klasę tworzy się i wykorzystuje tak samo jak wskaźniki do innych typów danych, np.NazwaKlasy obiekt;NazwaKlasy *wsk; // deklaracja wskaźnikawsk=&obiekt; // pobranie adresu obiektuwsk->dana=wartość; // dostęp do danychwsk->funkcja(); // dostęp do funkcjiNazwaKlasy o2= *wsk; // "wyciągnięcie" obiektu • Wewnątrz funkcji składowych klasy możliwe jest odczytanie adresu obiektu, na rzecz którego wywołano daną funkcję.Zawarty jest on we wskaźniku this.class klasa{ void adres() { printf ("this=%p\n", this) }}; Podstawy programowania - Programowanie obiektowe - klasy i obiekty
Przeciążanie operatorów • Klasa może tworzyć specjalne funkcje, które zmieniają sens standardowych operatorów, jeżeli będą one odnosić się do obiektów tej klasy • Nie można: • Wymyślić własnego operatora • Zmienić argumentowości ani priorytetów operatorów • Przeciążać operatorów: . .* :: ?: • Wykorzystanie tego mechanizmu pozwala pisać kod bardziej zwięzły, a jednocześnie czytelny • Typowy przykład zastosowania to klasa Macierz lub Wektor, dla których przeciąża się operatory algebraiczne, co pozwala na zapisywanie w kodzie obliczeń zgodnie z algebrą macierzową. • Inny przykład znamy z obiektów cin i cout, dla których przeciążono operatory przesunięć bitowych >> i << przykład: OPERATORY.CPP Podstawy programowania - Programowanie obiektowe - klasy i obiekty