Pobieranie prezentacji. Proszę czekać

Pobieranie prezentacji. Proszę czekać

Programowanie obiektowe

Podobne prezentacje


Prezentacja na temat: "Programowanie obiektowe"— Zapis prezentacji:

1 Programowanie obiektowe

2 Plan prezentacji Wprowadzenie
Podejście nie obiektowe przy tworzeniu oprogramowania Charakterystyka oprogramowania obiektowego Paradygmaty obiektowości Wprowadzenie do programowania obiektowego w C++ Pojęcie klasy Podsumowanie

3 Podejście nie obiektowe przy tworzeniu oprogramowania (1)

4 Podejście nie obiektowe przy tworzeniu oprogramowania (2)

5 Charakterystyka oprogramowania obiektowego
Obiekt posiada zestaw własnych danych z operacjami (metodami) wspólnymi z innymi podobnymi obiektami – są to składowe klasy. Przykłady obiektów Produkt: zna swoje atrybuty potrafi obliczyć swoją cenę brutto na podstawie ceny netto oraz dodatkowych atrybutów jak podatek oraz promocja. Zakup: wie, jaki i ile produktu zakupiono potrafi obliczyć swoją wartość na podstawie otrzymanej ceny brutto i liczby zakupionego produktu Rachunek: wie, ilu dokonano zakupów sumując wartości wszystkich zakupów uzyskuje swoją wartość.

6 Perspektywy rozumienia obiektów
Perspektywa koncepcji (modelu konceptualnego) obiekt jest zbiorem różnego rodzaju odpowiedzialności Perspektywa specyfikacji (modelu projektowego) obiekt jest zbiorem metod (zachowań), które mogą być wywoływane przez metody tego obiektu lub innych obiektów Perspektywa implementacji (kodu źródłowego) obiekt składa się z kodu metod i danych oraz interakcji między nimi

7 Prosty sposób identyfikacji klas
Klasa zawiera metody używane przez wiele obiektów tej klasy np. klasa TProdukt zawiera metody używane przez wiele obiektów Produkt o różnych wartościach tych samych typów atrybutów Klasa zawiera opis danych (atrybutów) używanych przez obiekt Klasa określa sposób dostępu do danych i metod Wniosek: Obiekt jest instancją klasy

8 Program obiektowy – obliczanie wartości rachunku
1. Start programu 2. Utworzenie instancji klasy TRachunek 3. Utworzenie w instancji klasy TRachunek instancji klasy TKolekcja zawierającej instancje klas TZakup; każda instancja klasy TZakup zawiera instancję klasyTProdukt oraz liczbę zakupionego produktu 4. Wywołanie metody obliczwartośćrachunku instancji klasy TRachunek, w której: 4.1. instancja klasy TRachunek pobiera instancję klasy TZakup i wywołuje jej metodę obliczwartośćzakupu w metodzie obliczwartośćzakupu instancja klasy TZakup wywołuje metodę obliczcenębrutto instancji klasy TProdukt w metodzie obliczcenębrutto instancja klasy TProdukt oblicza cenę brutto na podstawie własnych atrybutów i zwraca wartość do metody obliczwartośćzakupu instancji klasy TZakup Metoda obliczwartośćzakupu oblicza wartość zakupu i zwraca wartość metody obliczwartośćrachunku 4.2. Metoda obliczwartośćrachunku dodaje otrzymaną wartość do wartości rachunku 4.3. Metoda obliczwartośćrachunku powtarza krok 4.1 tak długo, aż wyczerpie instancje klasy TZakup w instancji kolekcji. Po jej wyczerpaniu przechodzi do 4.4 4.4. Metoda obliczwartośćrachunku, jeśli zostaną wyczerpane te instancje, zwraca wartość bieżącego rachunku 5. Koniec programu

9 Schemat blokowy – algorytm obliczania wartości rachunku

10 Diagram sekwencji UML – obiektowy sposób obliczania rachunku

11 Paradygmaty obiektowości (1)
Klasy abstrakcyjne Dziedziczenie Hermetyzacja Polimorfizm Agregacja

12 Paradygmaty obiektowości (2)
W programie Obliczanie wartości rachunku wystąpiła klasa typu TKolekcja zawierająca instancje klasy typ TZakup. W przypadku wprowadzenia nowej klasy typu TZakup1 np. z powodu zmiany strategii obliczania wartości zakupu towaru mogłaby ulec zmianie również klasa TKolekcja. Aby uniezależnić się od tego zjawiska umieszcza się w kolekcji taki typ klasy, który pozwala na umieszczanie instancji klas wyspecjalizowanych w odniesieniu do tej klasy np. klasy TZakup i TZakup1. Sama klasa uogólniona np. TObiekt nie może posiadać instancji – służy jedynie do uogólnienia wybranych właściwości wielu klas obsługiwanych przez jedną klasę TKolekcja. Taka uogólniona klasa nazywa się klasą abstrakcyjną. Klasa abstrakcyjna może wystąpić w perspektywach koncepcji, specyfikacji lub implementacji.

13 Paradygmaty obiektowości (3)
Dziedziczenie - Klasy TZakup oraz TZakup1, które są klasami wyspecjalizowanymi klasy abstrakcyjnej np. TObiekt, powstają dzięki dziedziczeniu po klasie abstrakcyjnej i są nazywane klasami pochodnymi. Można utworzyć wiele klas, które dziedziczą od klasy TObiekt wspólne dane i metody związane z przechowywaniem w kolekcji i mogą różnie implementować obliczanie wartości zakupionego produktu dodając nowe atrybuty i nowe metody np.: w klasie pochodnej TZakup obliczanie wartości zakupu polega na pomnożeniu ilości produktu przez cenę brutto otrzymaną od swojego produktu klasie pochodnej TZakup1 obliczanie wartości zakupu polega na obliczeniu tej wartości po dobraniu korekty ceny zakupu w zależności od ilości zakupionego produktu

14 Paradygmaty obiektowości (4)
Hermetyzacja - W systemach obiektowych rozróżnia się następujące rodzaje dostępu: publiczny – dla obiektów dowolnej klasy chroniony – tylko dla obiektów danej klasy i obiektów pochodnych prywatny – tylko dla obiektów danej klasy. Dostęp prywatny do składowych obiektów typu TZakup oznacza, że obiekt typu TRachunek nie zna jego atrybutów typu TProdukt oraz ilości produktu. To samo dotyczy nowych atrybutów w klasie TZakup1. Oznacza to brak wrażliwości kodu klasy TRachunek na zmiany w kodzie prywatnych składowych tych klas. Natomiast klasa TRachunek jest zainteresowana wartością zakupu obliczaną przez obiekty typu TZakup i TZakup1 za pomocą metody obliczwartośćzakupu, dlatego dostęp do tej metody musi być publiczny. Ewentualne błędy w klasie TRachunek nie powodują błędów w klasach TZakup i TZakup1 oraz błędy w tych klasach nie powodują błędów w kodzie klasy TRachunek. Wynika to z separacji kodu wywoływanych metod publicznych.

15 Paradygmaty obiektowości (5)
Polimorfizm - Obiekt typu TKolekcja w obiekcie TRachunek może przechowywać obiekty różnych typów klas pochodnych klasy TObiekt np. obiekty typu TZakup i TZakup1. Obiekty tych klas mogą mieć różny algorytm obliczania wartości zakupionego towaru w metodzie obliczwartośćzakupu, wynikający z dziedziczenia. Dla obiektu typuTRachunek nie jest ważny ten sposób, tylko wynik obliczeń wartości zakupu po wywołaniu tej metody - dlatego nie musi on rozróżniać typów obiektów TZakup i TZakup1. Taka właściwość klas pochodnych jest nazywana polimorfizmem.

16 Paradygmaty obiektowości (6)
Agregacja - Obiekt klasy TRachunek składa się z instancji kolekcji obiektów klas pochodnych od klasy abstrakcyjnej typu TObiekt. Obiekty klasy TZakup lub TZakup1 zawierają obiekty typu TProdukt. Taka właściwość polegająca na tym, że obiekt zawiera inne obiekty, nazywa się agregacją. Jest to inny sposób budowy klasy niż budowa nowej klasy za pomocą dziedziczenia.

17 Wprowadzenie do programowania obiektowego w C++ (1)
Główne zasady programowania obiektowego: hermetyzacja, dziedziczenie, polimorfizm Pojecie klasy: sposoby deklarowania i definiowania składowych klasy Atrybuty dostępu do składowych - private, protected i public wspierające hermetyzacje Obiekty automatyczne, statyczne i dynamiczne Konstruktory i destruktory Składowe klasy typu static Zmienne referencyjne, przekazywanie parametrów przez referencje, autoreferencja Pliki nagłówkowe, dyrektywy preprocesora, programy wielo-plikowe

18 Hermetyzacja Realizacja:
Hermetyzacja (enkapsulacja) - ochrona przed bezpośrednim dostępem do danych zawartych w klasie/obiekcie Realizacja: Do danych umieszczonych w klasie należy się odwołać jedynie za pośrednictwem metod tej klasy/obiektu Dostęp do składowych klasy można ograniczać specyfikatorami dostępu: private, protected, public

19 Dziedziczenie (1) Dziedziczenie - Budowa nowych klas (nadklas) na podstawie własności klas istniejących (podklas) Przykłady -Drzewo hierarchii stanowisk: A3-pracownik, C3-projektant, D3-kierownik, B3-czasowy, F3-konsultant, E3-czasowy projektant, G3-dyrektor Przykłady -Drzewo pojazdów: A2-pojazd, B2-samochód, C2-samochód osobowy, D2-łódź, E2-motorówka, F2-amfibia

20 Dziedziczenie (2)

21 Polimorfizm Polimorfizm - Uogólnianie pewnych cech na poziomie korzenia drzewa dziedziczenia w celu uproszczenia obsługi klas/obiektów z całej rodziny

22 Pojęcie klasy: sposoby deklarowania i definiowania składowych klasy (1)
Klasa jest typem danych definiowanym przez użytkownika Klasa stanowi połączenie: innych typów danych (predefiniowanych lub definiowanych przez użytkownika) funkcji przeznaczonych do przetwarzania tych danych (metody) Składnia klasy: class"|| "struct"|| "union nazwa klasy [:lista klas bazowych] { lista składowych klasy }; lista klas bazowych * - opcjonalna lista klas, od których dziedziczy dana klasa lista składowych klasy - deklaruje składowe klasy, czyli dane i metody Przykład klasy Dostęp do składowych private (domyślny), protected i public. Deklaracja składowych wewnątrz klasy. Definicja składowych na zewnątrz klasy – kod metod występuje w jednym miejscu i jest wspólny dla wszystkich obiektów, które są instancją tej klasy

23 Pojęcie klasy: sposoby deklarowania i definiowania składowych klasy (2)
// #include <iostream.h> class TProdukt1 { //protected: string nazwa; float cena; public: float Podaj_cene(); void Nadaj_cene(float ); string Podaj_nazwe (); void Nadaj_nazwe(string ); int Porownaj_produkty(TProdukt1& ); void Wyswietl(); }; składowe są tylko deklarowane wewnątrz ciała klasy

24 Pojęcie klasy: sposoby deklarowania i definiowania składowych klasy (3)
float TProdukt1::Podaj_cene() { return cena; } void TProdukt1::Nadaj_cene(float cena_) { cena = cena_; } string TProdukt1::Podaj_nazwe () { return nazwa; } void TProdukt1::Nadaj_nazwe(string nazwa_) { nazwa = nazwa_;} int TProdukt1::Porownaj_produkty(TProdukt1& p) { return Podaj_nazwe() == p.Podaj_nazwe() && Podaj_cene() == p.Podaj_cene(); } void TProdukt1::Wyswietl() { cout<<"Cena produktu: "<<cena<< ", Nazwa produktu: "<<nazwa<<endl; } definicja metod poza ciałem klasy

25 Atrybuty dostępu do składowych - private, protected i public
lista składowych klasy: [specyfikator dostępu :] lista składowych klasy private: sekcja prywatna (domyślna dla class) -składowe klasy są widoczne tylko w obrębie składowych danej klasy oraz w funkcjach/ klasach zaprzyjaźnionych protected: sekcja zabezpieczona - składowe są widoczne jedynie tylko w obrębie innych składowych klasy, składowych klas dziedziczących oraz w funkcjach/ klasach zaprzyjaźnionych public: sekcja publiczna (domyślna dla struct i union)- składowe są widoczne w całym programie

26 Dostęp do składowych private (domyślny), protected i public (1)
// #include <iostream.h> class TProdukt1 { //protected: string nazwa; float cena; public: float Podaj_cene(); void Nadaj_cene(float ); string Podaj_nazwe (); void Nadaj_nazwe(string ); int Porownaj_produkty(TProdukt1& ); void Wyswietl(); };

27 Dostęp do składowych private (domyślny), protected i public (2)
float TProdukt1::Podaj_cene() { return cena; } void TProdukt1::Nadaj_cene(float cena_) { cena = cena_; } string TProdukt1::Podaj_nazwe () { return nazwa; } void TProdukt1::Nadaj_nazwe(string nazwa_) { nazwa = nazwa_;} int TProdukt1::Porownaj_produkty(TProdukt1& p) { return Podaj_nazwe() == p.Podaj_nazwe() && Podaj_cene() == p.Podaj_cene(); } void TProdukt1::Wyswietl() { cout<<"Cena produktu: "<<cena<<", Nazwa produktu: "<<nazwa<<endl; }

28 Dostęp do składowych private (domyślny), protected i public (3)
int main(int argc, char* argv[]) { TProdukt1 produkt1, produkt2; produkt1.Nadaj_cene(3.5); produkt1.Nadaj_nazwe("Zeszyt"); produkt2.Nadaj_cene(1.6); // 3.5 produkt2.Nadaj_nazwe("Atrament"); //”Zeszyt” produkt1.Wyswietl(); produkt2.Wyswietl(); //cout<< produkt1.nazwa<<endl; if (produkt1.Porownaj_produkty(produkt2)) cout<<"Produkty maja rowne atrybuty"<<endl; else cout<<"Produkty nie maja rownych atrybutow"<<endl; cin.get(); return 0; } Można wywoływać składowe typu public w programie. Nie można skompilować programu, gdy atrybut nazwa jest typu private lub protected

29 Konstruktory Konstruktory - metody o nazwie klasy, wywoływane zawsze podczas tworzenia obiektu Są to metody domyślne lub jawne zadeklarowane o różnej liście parametrów. Domyślny zwykły konstruktor bezparametrowy: nazwa_klasy(); Domyślny konstruktor kopiujący: nazwa_klasy(nazwa_klasy&); Jawne zwykłe konstruktory z parametrami i jeden bez parametrów– albo istnieje jeden domyślny, albo dowolna liczba jawnych konstruktorów Jawny konstruktor kopiujący jest tylko jeden i posiada identyczny nagłówek jak konstruktor kopiujący domyślny – albo istnieje domyślny albo jawny Konstruktor kopiujący jawny lub domyślny jest wywołany podczas: przekazywania obiektów przez wartość do funkcji/metody zwracania obiektu przez wartość jako wyniku funkcji/metody inicjowania definiowanego obiektu obiektem tej samej klasy. Pozostałe konstruktory (domyślny lub jawne) są wywoływane podczas: definiowania zmiennych obiektowych alokacji pamięci dla obiektów dynamicznych za pomocą operatora new.

30 Destruktory Destruktor - tylko jedna metoda bezparametrowa ~nazwa_klasy() Może być zdefiniowany jawnie lub jest domyślny. Domyślny destruktor istnieje zawsze, gdy nie zdefiniowanego jawnego destruktora. Jawna definicja destruktora likwiduje destruktor domyślny. Jawna definicja destruktora jest wymagana do zwolnienia pamięci przeznaczonej na dynamiczne składowe klasy lub wykonania pewnych czynności związanych z usuwanym obiektem. Jest ona wywoływana zawsze podczas usuwania obiektu z pamięci podczas wywołania operatora delete przy usuwaniu obiektu dynamicznego, dla pozostałych obiektów po wyjściu z bloku ich definicji.

31 Konstruktory i destruktory domyślne (1)
// #include <iostream.h> class TProdukt1 { // protected: string nazwa; float cena; public: float Podaj_cene() { return cena; } void Nadaj_cene(float cena_) { cena = cena_;} string Podaj_nazwe () { return nazwa; } void Nadaj_nazwe(string nazwa_) { nazwa = nazwa_;} int Porownaj_produkty(TProdukt1& p) { return Podaj_nazwe()==p.Podaj_nazwe() && Podaj_cene()==p.Podaj_cene(); } void Wyswietl() { cout<<"Cena produktu: "<<cena<<", Nazwa produktu: "<<nazwa<<endl; } }; Deklaracja i definicja składowych wewnatrz klasy. Są to domyślnie składowe typu inline, których kod „wkleja” się do kodu programu w miejscu ich wywołania – duży program może szybciej działać, ponieważ nie traci czasu na wywołanie metody, ale może mieć większe rozmiary

32 Konstruktory i destruktor domyślne (2)
int main(int argc, char* argv[]) { TProdukt1 produkt1, produkt2; produkt1.Nadaj_cene(3.5); produkt1.Nadaj_nazwe("Zeszyt"); produkt2.Nadaj_cene(1.6); // 3.5 produkt2.Nadaj_nazwe("Atrament"); //”Zeszyt” produkt1.Wyswietl(); produkt2.Wyswietl(); //cout<< produkt1.nazwa<<endl; if (produkt1.Porownaj_produkty(produkt2)) cout<<"Produkty maja rowne atrybuty"<<endl; else cout<<"Produkty nie maja rownych atrybutow"<<endl; cin.get(); return 0;} Można wywoływać składowe typu public w programie. Nie można skompilować programu, gdy atrybut nazwa jest typu private lub protected

33 Konstruktory i destruktor jawne (1)
Zastosowanie konstruktora kopiującego przy przekazywaniu obiektu przez wartość oraz tworzenia nowego obiektu przez przypisanie do niego istniejącego obiektu (tworzenie kopii obiektu) // #include <iostream.h> class TProdukt1 { //protected: string nazwa; float cena; public: TProdukt1(string, float ); TProdukt1(TProdukt1&); ~TProdukt1(); float Podaj_cene(); void Nadaj_cene(float ); string Podaj_nazwe (); void Nadaj_nazwe(string ); int Porownaj_produkty(TProdukt1 ); void Wyswietl(); }; Konstruktor zwykły z parametrami Konstruktor kopiujący Destruktor Tutaj zostanie przekazana kopia obiektu typu TProdukt1 (przekazanie przez wartość) za pomocą wywołanego konstruktora kopiującego – w tym programie jawnego, lecz może to zrobić równie konstruktor domyślny

34 Konstruktory i destruktor jawne (2)
TProdukt1::TProdukt1(string nazwa_, float cena_) { cout<<"Wywolany zwykly konstruktor z parametrami"<<endl; nazwa = nazwa_; cena = cena_; } TProdukt1::TProdukt1(TProdukt1& p) { cout<<"Wywolany konstruktor kopiujacy"<<endl; nazwa = p.nazwa; cena = p.cena; } TProdukt1::~TProdukt1() { cout << "Wywolany destrutor"<<endl; } float TProdukt1::Podaj_cene() { return cena; } void TProdukt1::Nadaj_cene(float cena_) { cena = cena_; } string TProdukt1::Podaj_nazwe () { return nazwa; } void TProdukt1::Nadaj_nazwe(string nazwa_) { nazwa = nazwa_;} int TProdukt1::Porownaj_produkty(TProdukt1 p) { return Podaj_nazwe()==p.Podaj_nazwe() && Podaj_cene()==p.Podaj_cene(); } void TProdukt1::Wyswietl() { cout<<"Cena produktu: "<<cena<<", Nazwa produktu: "<<nazwa<<endl; } Tutaj zostanie przekazana kopia obiektu typu TProdukt1 (przekazanie przez wartość) za pomocą wywołanego konstruktora kopiującego

35 Konstruktory i destruktor jawne (3)
int main(int argc, char* argv[]) { { TProdukt1 produkt1("Zeszyt", 3.5), produkt2("Atrament", 1.6); // 1, 2 TProdukt1 produkt3 = produkt2; //3 produkt1.Wyswietl(); produkt2.Wyswietl(); produkt3.Wyswietl(); if (produkt1.Porownaj_produkty(produkt2)) // 4, 5 cout<<"Produkty maja rowne atrybuty"<<endl; else cout<<"Produkty nie maja rownych atrybutow"<<endl; } // 6, 7, 8 cout<<"Tutaj juz nie ma obiektow"<<endl; //produkt1.Wyswietl(); cin.get(); return 0; } 1 2 3 4 5 6 7 8

36 Rodzaje zmiennych typu obiektowego
Automatyczne - są definiowane (tworzone) wewnątrz dowolnego bloku funkcji. Są usuwane, gdy wychodzi się z danego bloku lub z funkcji. Statyczne: definiowane poza funkcjami jako zmienne globalne (o zasięgu wieloplikowym deklarowane jako extern) jako globalne zmienne typu static o zasięgu jednoplikowym wewnątrz dowolnej funkcji, gdy definicja jest poprzedzona słowem static (dostępne są tylko wewnątrz działającej funkcji z zachowaniem wartości wyznaczonych podczas poprzedniego wywołania). Istnieją one przez cały czas działania programu i usuwane są po jego zakończeniu. Dynamiczne* - tworzone jawnie w czasie działania programu na stercie (heap) za pomocą operatora new i usuwane za pomocą operatora delete

37 Statyczne, globalne obiekty wejścia cin i wyjścia cout
// #include <iostream.h> int main(int argc, char* argv[]) { cout << "Prosty program\n"; cin.get(); return 0;} // { int liczba; cout << "Podaj liczbe całkowita: "; cin >> liczba; cin.get(); cout << "Podano liczbe: " << liczba << endl; return 0; } #include <iostream> extern ostream cout; ostream cout; #include <iostream> extern istream cin; istream cin;

38 Obiekty automatyczne int main(int argc, char* argv[]) // funkcja main dla klasy TProdukt1 { //definiowanie automatycznych obiektow { TProdukt1 produkt1("Zeszyt", 3.5), produkt2("Atrament", 1.6); // 1, 2 produkt1.Wyswietl(); produkt2.Wyswietl(); if (produkt1.Porownaj_produkty(produkt2)) // 3, 4 cout<<"Produkty maja rowne atrybuty"<<endl; else cout<<"Produkty nie maja rownych atrybutow"<<endl; } // 5, 6 cout<<"Tutaj juz nie ma obiektow"<<endl; //produkt1.Wyswietl(); cin.get(); return 0; } W metodzie Porównaj_produkty pojawia się obiekt automatyczny Poza blokiem nie ma obiektów automatycznych 1 2 3 4 5 6

39 Obiekty statyczne int main(int argc, char* argv[]) // klasa TProduk1
{ //definiowanie statycznych obiektów { static TProdukt1 produkt1("Zeszyt", 3.5), produkt2("Atrament", 1.6); // 1, 2 produkt1.Wyswietl(); produkt2.Wyswietl(); if (produkt1.Porownaj_produkty(produkt2)) // 3, 4 cout<<"Produkty maja rowne atrybuty"<<endl; else cout<<"Produkty nie maja rownych atrybutow"<<endl; } cout<<"Tutaj juz nie ma dostepu do obiektow statycznych"<<endl; //5 //produkt1.Wyswietl(); cin.get(); return 0;} W metodzie Porównaj_produkty pojawia się obiekt automatyczny Poza blokiem są dalej obiekty statyczne (brak wywołanych destruktorów), jednak nie mona wywołać ich metod poza blokiem definicji 1 2 3 4 5


Pobierz ppt "Programowanie obiektowe"

Podobne prezentacje


Reklamy Google