• Nie Znaleziono Wyników

Wstęp do programowania obiektowego

N/A
N/A
Protected

Academic year: 2021

Share "Wstęp do programowania obiektowego"

Copied!
28
0
0

Pełen tekst

(1)

Wstęp do programowania obiektowego

Wykład 2

1

(2)

CECHY I KONCEPCJA

PROGRAMOWANIA

OBIEKTOWEGO

(3)

Cechy programowania obiektowego

Dla wielu problemów podejście obiektowe jest zgodne z rzeczywistością (łatwe do

przyswojenia przez człowieka; dobrze odzwierciedlające sposób, w jaki ludzie myślą o świecie).

PO nie daje żadnych nowych efektów w gotowym programie

Zastosowanie PO nie jest widoczne dla użytkownika

Zastosowanie PO może pogorszyć wydajność obliczeniową programu (w porównaniu do analogicznego programu strukturalnego)

3

(4)

C++ jest językiem zarówno obiektowym, jak i imperatywnym/strukturalnym/proceduralnym.

Języki programowania z cechami obiektowości to m.in.: C#, Java, Object Pascal, Lisp, Ruby,

Python, PHP5.

(5)

Koncepcja programowania obiektowego

Otaczający nas świat to różnego rodzaju przedmioty.

Tworząc program komputerowy dokonujemy pewnego ich odwzorowania.

W programowaniu proceduralnym funkcje i

zmienne dotyczące danego przedmiotu nie są ze sobą logicznie powiązane.

W programowaniu obiektowym dokonuje się powiązania metod (funkcji programu) z danymi (zmiennymi) definiującymi przedmiot.

Wszystko to grupuje się w klasie zawierającej w jednym miejscu zarówno dane definiowanego przedmiotu, jak i dotyczące go funkcje.

5

(6)

Podstawowe definicje

Klasa – (częściowa lub całkowita) definicja dla obiektu - opis budowy i działania obiektów

Obiekt – fizyczna instancja (ucieleśnienie, egzemplarz) klasy. Jest to struktura zawierająca:

dane

metody, czyli funkcje służące do wykonywania na tych danych określonych zadań.

Każdy obiekt ma trzy cechy:

tożsamość, czyli cechę umożliwiającą jego identyfikację i odróżnienie od innych obiektów;

stan, czyli aktualny stan „własnych” danych;

zachowanie, czyli zestaw metod wykonujących operacje na tych danych.

(7)

UKRYWANIE IMPLEMENTACJI:

HERMETYZACJA (ENKAPSULACJA)

7

(8)

Hermetyzacja

„Zwykłemu użytkownikowi” niepotrzebna jest znajomość wewnętrznej budowy urządzeń.

Do codziennej obsługi, wystarczą nam udostępnione

bezpieczne manipulatory. Mamy dostęp tylko do wybranych metod urządzenia (np. manipulatory telewizora). W ten

sposób część (bardziej skomplikowanych) funkcji jest przed nami ukryta.

Analogicznie jest w programowaniu obiektowym:

Hermetyzacja (enkapsulacja) - ograniczenie

bezpośredniego dostępu do niektórych pól obiektów,

ewentualnie umożliwienie ich modyfikacji poprzez metody.

(9)

Specyfikatory (etykiety) dostępu

O dostępności pól i metod decydują tzw. specyfikatory dostępu: public, private i protected.

W C++ w ciele klasy deklaruje się sekcje (zawierające jedną lub więcej składowych):

public – składowe widoczne globalnie, dla wszystkich, np. z maina;

private – składowe widoczne tylko dla danej klasy;

protected – składowe widoczne tylko dla danej klasy oraz klas dziedziczących.

class Punkt { public:

int x, y;

double odległość (int xx, int yy) {return sqrt((x-xx)*(x-xx)+(y- yy)*(y-yy));}

private:

void zeruj () {x = 0; y = 0;}

protected:

double przesuń (int dx, int dy) {x+=dx; y+=dy;}

}; 9

(10)

Etykieta dotyczy występujących po niej metod i pól.

Liczba etykiet jest dowolna (mogą się powtarzać).

W przypadku braku etykiety domyślnie jest przypisana sekcja prywatna.

class Punkt{

void fun1(){…} //prywatna, bo domyślna

protected:

int fun2(){ … } int y;

private:

float fun3(){…}

int x;

public:

double fun4(){…}

};

(11)

Konwencja nazewnictwa get/set/is

Kiedy pole jest zadeklarowane jako prywatne możemy umożliwić :

odczyt wartości pola przez metodę publiczną nazywaną get<nazwa pola>().

modyfikację wartości pola przez metodę publiczną nazywaną set<nazwa pola>.

class Punkt {

private:

int x;

int y;

public:

int getx(){return x;}

int gety(){return y;}

void setx(int xx){x=xx;}

void sety(int yy){

if (yy>=0) y=yy;}

};

11

(12)

W C++ jest to tylko konwencja

nazewnictwa (zalecany sposób tworzenia nazw metod do odczytu i zapisu pól

prywatnych), a nie obowiązkowy element języka.

Stosuje się to w wielu językach obiektowych, niekiedy jest to też

mechanizm wbudowany (jak np. akcesory set, get w C#).

(13)

Korzyści z hermetyzacji

Funkcje getx(), gety(), setx() i sety() znajdują się w

sekcji public i są widoczne poza obiektem klasy. Pola x i y nie są widoczne poza obiektem klasy, ale jedynie wewnątrz obiektu (mają do niej dostęp metody klasy, czyli m.in. nasze funkcje getx(), gety(), setx() i sety() ).

Z tego względu te funkcje stanowią "interfejs"

dostępu do pól obiektu klasy Punkt.

Daje to nam kontrolę nad zapisem i odczytem do pól x i y poprzez odpowiednie definicje metod (możemy sprawdzić, odrzucić czy zabronić modyfikacji pola).

Standardowe nazwy takich metod ułatwiają czytanie kodu.

Można wyświetlić zmiany użytkownikowi w

odpowiedzi na zmianę wartości zmiennej (wywołanie settera powoduje też wyświetlenie tekstu lub

aktualizację kontrolki GUI)

13

(14)

Dwie role programistów PO

Twórca klas – tworzy biblioteki kodu do

wykorzystania, np. klasy, ich metody i dane

Programista-klient – używa stworzonego kodu, czyli gotowych klas: tworzy obiekty, wywołuje metody itp.

Dobrze jest ukryć przed programistą-klientem nieistotne dla niego szczegóły implementacji, które mogłyby być niewłaściwie użyte. W ten sposób zmniejsza się ryzyko popełnienia przez niego błędów w używaniu gotowych bibliotek

(klas). Takie postępowanie to właśnie ukrywanie implementacji (hermetyzacja).

(15)

Modyfikacje bibliotek

Ukrywanie implementacji pozwala też na modyfikację przez twórcę klas szczegółów udostępnianych bibliotek, bez większego wpływu na kod wykorzystujący te

biblioteki (kod napisany przez programistę-klienta).

Modyfikacje to na przykład rozszerzanie funkcjonalności biblioteki czy

optymalizacja kodu.

15

(16)

KONSTRUKTORY I

DESTRUKTORY

(17)

Geneza

Przyczyną wielu błędów jest to, że programista zapomina o inicjalizacji

zmiennych lub "końcowych porządkach".

W programowaniu obiektowym

wprowadzono więc półautomatyczny mechanizm inicjacji i "sprzątania":

odpowiednio: konstruktory i destruktory.

17

(18)

Konstruktor

Przy tworzeniu obiektu zawsze

wywoływany jest konstruktor (specjalna funkcja składowa klasy).

Podstawowym zadaniem konstruktora jest inicjalizacja (nadanie odpowiednich wartości) polom tworzonego obiektu.

(19)

Cechy konstruktora:

Nazwa konstruktora jest taka sama jak nazwa klasy;

nie zwraca żadnego wyniku;

może przyjmować parametry;

Parametrami konstruktora nie mogą być obiekty klasy do której należy, ale mogą być referencje do tych obiektów (w C++);

Nie może być wywołany jak zwykła metoda (bez tworzenia obiektu);

Najczęściej jest publiczny.

19

(20)

Dwa sposoby inicjalizacji pól w C++

1. W konstruktorze przy użyciu instrukcji przypisania, np.:

Punkt(int xx, int yy) { x = xx; y = yy;

}

2. W konstruktorze, przy użyciu listy inicjacyjnej, np.:

Punkt(int xx, int yy) : x(xx), y(yy) {}

Dopuszczalne są też rozwiązania mieszane.

(21)

Konstruktor domyślny

W momencie tworzenia obiektu zawsze wywoływany jest jakiś konstruktor.

Jeżeli w klasie nie został zdefiniowany

żaden konstruktor, to kompilator dodaje (niewidoczny w kodzie) konstruktor

domyślny (bezparametrowy).

21

(22)

Konstruktor bezparametrowy

Często też definiuje się własny

konstruktor bezparametrowy. Konstruktor bezparametrowy najczęściej nadaje

polom wartości domyślne.

(23)

Tworzenie obiektów z

wykorzystaniem konstruktorów:

Punkt p(20,40), p1, p2;

Punkt* wskp1 = new Punkt(30, 35);

Punkt* wskp2 = new Punkt();

Punkt* wskp3 = new Punkt;

23

(24)

Konstruktor kopiujący

Zadaniem konstruktora kopiującego jest

utworzenie nowego obiektu jako dokładnej kopii obiektu istniejącego. Nagłówek zwykle ma postać:

<nazwa klasy>(const <nazwa klasy>&) Przykład:

Prostokąt(const Prostokąt& p)

Przy braku definicji konstruktora kopiującego, kompilator dodaje domyślny konstruktor

kopiujący, który kopiuje „pole po polu” (jest to tzw. kopia płytka i niekiedy to nie wystarcza).

(25)

Destruktor

W momencie niszczenia obiektu (np.: koniec zakresu widoczności obiektu lokalnego) wywoływany jest destruktor – zdefiniowany w klasie lub domyślny.

Celem definiowania destruktora może być np. zwolnienie zaalokowanej ręcznie pamięci, używanych zmiennych dynamicznych, itp. porządki.

Definicja destruktora:

~<nazwa klasy>()

{ <deklaracje zmiennych>

<instrukcje>, itp. }

Cechy destruktora:

nie ma parametrów,

nie ma typu wyniku

w klasie może wystąpić tylko jeden destruktor

nie można go wywołać jak zwykłej metody

25

(26)

DIAGRAMY KLAS W NOTACJI

UML

(27)

Schemat klasy w UML

Nazwa

Atrybuty (zmienne klasowe)

Metody (funkcje)

27

Żarówka

- bool włączona

# int moc

+ void włącz() + void wyłącz()

Aby używać typu bool należy dopisać na początku programu: #include <stdbool.h>

Symbole modyfikatorów dostępu:

- private + public

# protected

(28)

Przykłady klas (UML)

Punkt (na płaszczyźnie)

Punkt (w przestrzeni 3D)

Telewizor

Człowiek

Szafa/Pokój/Paczka

Odcinek

Wektor

Wielokąt (budowany z punktów)

Wielokąt (budowany z odcinków)

Cytaty

Powiązane dokumenty

(metoda operatorowa) jest wywoływana na rzecz obiektu, który jest po lewej od operatora (dane tego obiektu są dostępne przez this, albo bezpośrednio przez nazwę). Drugi argument

wsk jest stałym wskaźnikiem do stałej int, ani nie można modyfikować obiektu pokazywanego przez wskaźnik, ani nie można pokazać tym wskaźnikiem na inny obiekt... PRZEŁADOWYWANIE

 Standardowo wywoływany jest konstruktor bezparametrowy (lub domyślny) klasy nadrzędnej..  Aby do konstrukcji podobiektu klasy bazowej

 Przeszukiwany jest stos wywołań funkcji w poszukiwaniu takiej, która zawiera obsługę wyjątku danego typu (czyli odpowiednią instrukcję catch).. ◦ Jeżeli

• Parametrami szablonów mogą być również szablony klas, jako tak zwane szablony parametrów szablonów.. Stack&lt;int, std::vector&gt;

 OutputIterator set_union (InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result);.  OutputIterator

Model dziedziny (uzupełniony): klasy, atrybuty klas oraz

 Jednostka programu, która zadeklarowała instancję klasy (obiekt), ma dostęp do publicznych bytów tej klasy, ale tylko poprzez tę instancję.  Każda instancja klasy ma