Języki i paradygmaty zaocz cz I


1
Pliki zawierają materiał ilustracyjny do wykładu:
(szczegółowe omówienie zagadnień odbywa się w trakcie
wykładu)
Studia zaoczne
Nazwa przedmiotu: Języki i paradygmaty
programowaniaE
Liczba godzin:
wykład  30 godz.
ćwiczenia laboratoryjne  30 godz.
Podstawowy Wprowadzenie do profesjonalnego tworzenia
cel oprogramowania w ujęciu obiektowym. Wykład jest
prowadzony metodą case study z położeniem nacisku
na metody implementacji.
PowiÄ…zania z Bazuje na:  Podstawy programowania
innymi Podbudowuje:  Inżynieria oprogramowania
przedmiotami
Program ramowy przedmiotu:
1. Podstawowe pojęcia: Paradygmat. Paradygmaty programowa-
nia. Programowanie strukturalne, proceduralne i obiektowe.
Przykłady.
2. Paradygmaty programowania obiektowego: Hermetyzacja,
dziedziczenie i polimorfizm. Modelowanie obiektowe. Dziedzina
problemu. Zakres obowiązków systemu.
3. Klasy i ich składowe. Struktura definicji klasy: atrybuty i usługi;
składowe prywatne, publiczne i chronione. Konstruktory i
2
destruktory, lista inicjalizacyjna. Konstrukcja podobiektów.
Konstruktory kopiujÄ…ce.
4. Programowanie obiektowe: Dziedziczenie klas. Rodzaje
dziedziczeń. Hierarchia klas. Funkcje wirtualne i czysto wirtualne.
Abstrakcyjne klasy bazowe. Dziedziczenie i polimorfizm.
5. Drugorzędne cechy klas i obiektów: Obiekty automatyczne,
dynamiczne i statyczne. Znaczenie wskaznika this. Składowe i
metody statyczne. Funkcje i klasy zaprzyjaznione.
6. Programowanie z wykorzystaniem wzorców: Wzorce funkcji i
klas. Wzorce metod.
7. Programowanie uogólnione: Organizacja bibliotek i kolekcji.
Biblioteka STL. Kolekcje standardowe vector i list.
8.Omwienie pozostałych paradygmatów programowania:
programowanie imperatywne, zdarzeniowe, logiczne i aspektowe.
Wykład ma charakter autorski.
Literatura uzupełniająca:
1. Stanley B. Lippman: Podstawy języka C++, WNT, 2001
2. Stanley B. Lippman: Istota języka C++ zwięzły opis, WNT, 2004
3. Andrzej Stasiewicz: C++ Ćwiczenia zaawansowane, Helion, 2005
4. David Vandevoorde: Język C++ ćwiczenia i rozwiązania, WNT,
2001
5. Stanley B. Lippman: Model obiektu w C++, WNT, 2001
6. Bjarne Stroustrup: Język C++, WNT, 1994-2000
http://wazniak.mimuw.edu.pl/index.php?title=Paradygmaty_programowa
nia/Wyk%C5%82ad_1:_Co_to_jest_paradygmat_programowania%3F
3
Jak się uczyć języka C++ ?
Cytaty [ Bjarne Stroustrup  twórca języka C++]
"Ucząc się języka C++ trzeba stale pamiętać o podstawowych
pojęciach, aby nie zagubić się w szczegółach technicznych języka.
Skupianie się na szczegółach może bardzo rozproszyć i przyczynić się
do niepełnego wykorzystania możliwości języka. Wszak nie powinno
się uczyć obcego języka ze słownika i opisu gramatyki !"
"Dopóki uczeń nie zrozumie istoty abstrakcyjnych typów danych i
programowania obiektowego, dopóty jedynym skutkiem będzie
niewłaściwe 'barokowe' użycie właściwości języka ..."
"Projektowanie i programowanie obiektowe, to zajęcie praktyczne, a
nie teoretyczne. Koncepcje stosowane tylko na przykładach
modelowych mogą stać się niebezpiecznymi 'religiami'."
1. Podstawowe pojęcia
Paradygmat to, jak podaje Słownik języka polskiego PWN,  przyjęty
sposób widzenia rzeczywistości w danej dziedzinie, doktrynie itp.
W informatyce paradygmat programowania rozumieć możemy jako
pewną filozofię podejścia do tworzenia programu. Wyraża się ona jednak
konkretnie poprzez zbiór mechanizmów, jakich programista używa,
pisząc program. Paradygmat programowania rozumie się również jako
ogół oczekiwań programisty wobec języka programowania i komputera,
na którym będzie działał program.
Poniżej wymieniono najczęściej używane podejścia do programowania,
które można utożsamiać z paradygmatami programowania. Podział ten nie
jest jednak ostry, a poza tym, szybko ewoluuje.
4
·ð Programowanie proceduralne
·ð Programowanie strukturalne (np. Pascal, C++, Ada, Modula)
·ð Programowanie funkcyjne (np. Haskell, Lisp, F#)
·ð Programowanie imperatywne
·ð Programowanie obiektowe (np. C++, Java, itd.)
·ð Programowanie uogólnione
·ð Programowanie zdarzeniowe
·ð Programowanie logiczne (np. Prolog)
·ð Programowanie aspektowe
Wiele paradygmatów jest dobrze znanych z tego, jakie praktyki są w nich
zakazane, a jakie dozwolone. Na przykład ścisłe programowanie
funkcyjne nie pozwala na tworzenie skutków ubocznych, w
programowaniu strukturalnym nie korzysta siÄ™ z instrukcji goto.
Zależności między paradygmatami programowania mogą przybierać
skomplikowane formy, ponieważ jeden język może wspierać wiele
różnych paradygmatów.
Dobrym przykładem jest tutaj język C++, który posiada elementy
programowania proceduralnego i strukturalnego, pozwala realizować
mechanizmy programowania uogólnionego, zdarzeniowego i
aspektowego. Jego siła tkwi jednak w podejściu obiektowym.
2. Paradygmaty programowania obiektowego
Programowanie proceduralne to paradygmat programowania zalecajÄ…cy
dzielenie kodu na procedury (funkcje), to jest fragmenty wykonujÄ…ce
ściśle określone operacje.
Procedury nie powinny korzystać ze zmiennych globalnych (w miarę
możliwości), lecz pobierać i przekazywać wszystkie dane (czy też
wskazniki do danych) jako parametry wywołania.
5
Programowanie strukturalne należy traktować jako rozszerzenie
podejścia proceduralnego. Zaleca ono hierarchiczne dzielenie programu na
mniejsze moduły, które komunikują się ze sobą przez dobrze określone
interfejsy.
Przykład:
1. Podejście proceduralne
struct DATA
{ int dzień, miesiąc, rok; }; // definicja typu danych
............................................................
DATA dzisiaj; // deklaracja zmiennej typu DATA
............................................................
// poniżej deklaracje funkcji obsługi danych typu DATA
void wstaw_date( DATA *, int, int, int);
void nast_data( DATA * );
void drukuj_date( const DATA * );
............................................................
// poniżej przykłady wywołania funkcji na rzecz zmiennych
wstaw_date(& dzisiaj, 27, 9, 2006);
drukuj_date(& dzisiaj);
To podejście skazane jest na rozdzielenie kodu:
żð definicji typów,
żð deklaracji zmiennych,
żð procedur obsÅ‚ugi tych struktur danych.
Każda zmiana któregokolwiek z tych elementów wymaga
sprawdzenia i ewentualnych korekt w pozostałych.
6
2. Podejście obiektowe
//poniżej definicja typu w postaci definicji klasy
class DATA
{ int dzień, miesiąc, rok;
public:
void ustaw( int, int, int);
void pobierz( int *, int *, int * );
void nast( void);
void drukuj( void );
};
............................................................
// poniżej deklaracja trzech zmiennych (obiektów) klasy DATA
DATA dzisiaj, moje_urodziny, data;
............................................................
// poniżej przykłady wywołania funkcji składowych klasy na rzecz obiektu
moje_urodziny.ustaw( 30, 12, 1950 );
dzisiaj.drukuj( );
żð Atrybuty obiektów klasy, jeÅ›li sÄ… prywatne, mogÄ… być obsÅ‚ugiwane
tylko przez własne metody klasy  paradygmat hermetyzacji, inaczej -
enkapsulacji.
żð Metody zadeklarowane w części publicznej definicji klasy stanowiÄ…
swoisty interfejs do obiektów klasy.
Korzyści wynikające z podejścia obiektowego:
·ð Å‚atwość rozbudowy i testowania oprogramowania,
·ð maÅ‚a wrażliwość na uszkodzenie kodu.
żð Klasa opisuje możliwie wiernie zbiór obiektów realnego Å›wiata w
kategoriach konkretnej dziedziny problemu podany z punktu widzenia
obowiązków systemu.
7
Każdy obiekt jest konkretną egzemplifikacją klasy, tak jak w klasycznym
ujęciu - zmienna jest egzemplifikacją typu.
Jednocześnie każdy obiekt jest składową dziedziny problemu i posiada:
- tożsamość (konkretną nazwę),
- stan (zbiór wartości atrybutów),
- zachowanie (metody).
typ
Nazwa klasy
(parametry, dane
Atrybuty klasy
synonimy
składowe, pola)
Metody klasy
(usługi, funkcje
składowe)
Dziedzina problemu jest słownikiem zawierającym wyłącznie te pojęcia,
które wiążą się ściśle z założonymi celami. Tak skonstruowany słownik
zawierać więc będzie nazwy najważniejszych klas w przyszłym systemie
informatycznym. Abstrahowanie pojęć w trakcie tworzenia definicji klas
nie może odbywać się w oderwaniu od celu, którym jest stworzenie
konkretnego, wykonującego określone obowiązki, systemu
informatycznego.
Zakres obowiązków systemu jest dość ogólną, ale kompletną specyfikacją
czynności realizowanych przez moduł systemu informatycznego.
Przykłady dziedzin problemu:
- ruch pacjentów w szpitalu,
- funkcjonowanie obiektu technicznego, np. samochodu,
komputera, centrali telefonii komórkowej.
 Głównym zadaniem programisty C++ jest dostarczenie klas i
hierarchii klas obiektowych S.B. Lippman
8
Główne paradygmaty programowania obiektowego to:
·ð hermetyzacja (kapsuÅ‚kowanie)
·ð dziedziczenie
·ð polimorfizm
Następny rozdział przybliży i rozwinie zagadnienia języka związane z
paradygmatem hermetyzacji i dopiero kolejne poświęcone będą
dziedziczeniu i polimorfizmowi.
3. Klasy i ich składowe
class < nazwa klasy >
{
private:
............................
protected:
............................
public:
............................
} < lista obiektów, wskazań i referencji do obiektów klasy > ;
o Elementy definicji w nawiasach ostrych <& > są opcjonalne, średnik
kończący definicję jest obowiązkowy.
o W każdej z trzech sekcji definicji klasy można umieszczać zarówno
dane składowe, jak i funkcje składowe.
o Specyfikatory sekcji mogą być użyte wielokrotnie w obrębie danej
definicji klasy.
o Nie określenie kwalifikatora dostępu (specyfikatora sekcji) w
pierwszej części definicji czyni składowe domyślnie prywatnymi.
o Kwalifikator private (sekcja prywatna) chroni pola obiektów klasy i
niektóre funkcje ( o znaczeniu lokalnym) przed użyciem z zewnątrz
obiektu.
o Pola i funkcje umieszczone w sekcji zabezpieczonej (kwalifikator
9
protected ) będą widoczne poza obiektem klasy wyłącznie w
obiektach klas pochodnych.
o Pola i funkcje umieszczone w sekcji publicznej (kwalifikator public )
będą widoczne poza obiektami klasy do końca modułu, w którym
klasa została zadeklarowana.
Metody publiczne służą do:
- sterowania obiektem,
- zmiany jego stanu,
- sterowania obiektami innych typów (komunikaty)
·ð Funkcje prywatne klasy majÄ… dostÄ™p ograniczony tylko do atrybutów
obiektu własnej klasy i nie są dostępne z zewnątrz klasy. Pełnią one
jednak ważną rolę w tak zwanych obiektach aktywnych.
·ð WartoÅ›ci atrybutów obiektu sÄ… zawsze okreÅ›lone. W ten sposób każdy
obiekt zawsze znajduje siÄ™ w pewnym stanie, wyznaczonym przez
zespół wartości jego atrybutów. Poszczególne obiekty mogą być
modyfikowane niezależnie od siebie przez te same, upoważnione do ich
modyfikacji funkcje.
·ð Wszystko, co obiekt "wie" jest wyrażone przez jego atrybuty. Wszystko
co obiekt może zrobić, lub co z nim można zrobić, jest zawarte w
funkcjach klasy, do której obiekt należy. Jednocześnie wszystko, co nie
istotne na zewnątrz obiektu, jest ukryte w jego wnętrzu i niedostępne z
zewnątrz. Obiekty mogą oddziaływać na siebie wyłącznie za pomocą
komunikatów, które polegają na wywołaniu metod innych klas.
Typowe klasy to:
·ð przedmioty fizyczne ( osoby, urzÄ…dzenia techniczne),
·ð role peÅ‚nione przez osoby (kierownik, wykÅ‚adowca, ksiÄ™gowa)
·ð zdarzenia ( zakup, rejestracja pojazdu),
·ð interakcja miÄ™dzy osobami lub zdarzeniami ( pożyczka, zamówienie,
połączenie telefoniczne),
·ð organizacja ( bank, szpital, wydziaÅ‚ ),
10
·ð pojÄ™cie ( jakość produktu ),
·ð dokumenty ( faktura, prawo jazdy),
·ð klasy bÄ™dÄ…ce interfejsami do systemów zewnÄ™trznych,
·ð klasy bÄ™dÄ…ce interfejsami do użytkowników systemu.
Weryfikacja klas i obiektów:
·ð nie można okreÅ›lić żadnych pól lub usÅ‚ug jawnych
®ð klasa jest zbyteczna,
·ð pola lub/i metody sÄ… pojedyncze ®ð na ogół można je schować w
innych klasach,
·ð istnieje tylko jeden obiekt dla klasy ®ð na ogół klasa jest
zbyteczna,
·ð brak zwiÄ…zków z innymi klasami ®ð klasa poza zakresem
obowiązków systemu.
o Wybór właściwych klas w modelu jest w znacznym stopniu
subiektywny.
Konstruktory
Konstruktory są funkcjami składowymi klasy, których zadaniem jest
tworzenie obiektów danej klasy.
class DATA
{ int dzień, miesiąc, rok;
public:
DATA( int, int, int); //konstruktor
. . . . . . . . . . . . . . . . . . .
};
// jawne użycie konstruktora w celu stworzenia obiektu nie dynamicznego
DATA dzisiaj = DATA(21, 2, 2008);
11
// niejawne użycie konstruktora w celu stworzenia obiektu nie
//dynamicznego
DATA moje_urodziny(12, 10, 1987);
Jest to najczęściej używana metoda tworzenia obiektów nie
dynamicznych.
Przeciążanie konstruktorów
class DATA
{ int dzień, miesiąc, rok;
public:
DATA( int, int, int);
DATA( int, int); // wystarczy podać dzień i miesiąc
DATA( int); // wystarczy podać dzień
DATA( ); // konstruktor bezparametrowy (domyślny)
DATA( const char * ); // data w postaci napisu do
// rozpakowania
};
Jak widać konstruktory są typowymi funkcjami przeciążonymi.
// przykłady użycia konstruktorów
DATA dzisiaj, d; DATA data(4); DATA dzien(5, 2);
DATA wielkanoc(  23 marzec 2008 );
W ramach ćwiczenia oceń, których konstruktorów użyto w każdym
przypadku ?
Zasady tworzenia i używania konstruktorów:
1. Identyfikator konstruktora jest taki sam jak nazwa klasy,
2. W deklaracji konstruktora nie wolno określać typu zwracanej
wartości, nawet void,
12
3. Wybór właściwego konstruktora odbywa się tak jak funkcji
przeciążonej,
4. Konstruktory nie sÄ… dziedziczone,
5. Nie można pobrać adresu konstruktora,
6. Konstruktor nie może być funkcją wirtualną.
Definiowanie konstruktorów za pomocą list inicjalizacyjnych,
konstruktory z parametrami domyślnymi
class PUNKT
{
int x, y;
unsigned kolor;
public:
// poniżej pełna definicja konstruktora z wykorzystaniem listy
// inicjalizacyjnej
PUNKT(void): x(0), y(0), kolor(0) { } (1)
// poniżej deklaracja konstruktora z parametrem domyślnym
PUNKT ( int _x, int _y, unsigned _kolor = 0); (2)
// poniżej deklaracja konstruktora jednoparametrowego
PUNKT ( unsigned _kolor); (3)
. . . . . . . . . . . . . . . . . . . . . . .
void UstawWsp( int _x, int _y);
void UstawKolor( unsigned _kolor);
void Rysuj( void);
};
// poniżej definicje zadeklarowanych wcześniej konstruktorów klasy
// PUNKT umieszczone na zewnÄ…trz klasy (z wykorzystaniem list
// inicjalizacyjnych)
PUNKT:: PUNKT( int _x, int _y, unsigned _kolor = 0):
x( _x ), y( _y ), kolor( _kolor ) { }
PUNKT:: PUNKT( unsigned _kolor ): x( 0 ), y( 0 ), kolor( _kolor ) { }
13
// poniżej definicja wybranej metody (zadeklarowanej w klasie)
// umieszczona na zewnÄ…trz klasy
void PUNKT:: UstawWsp( int _x, int _y) { x = _x; y = _y; }
Poniżej przykłady poprawnego użycia konstruktorów zadeklarowanych w
klasie PUNKT do tworzenia:
żð obiektów nie dynamicznych:
PUNKT p1, p2( 1, 1 ), p3( 10, 10, 5 ), p4( 1 );
W ramach ćwiczenia oceń, którego z trzech konstruktorów klasy
PUNKT użyto w każdym przypadku ?
żð obiektu dynamicznego:
PUNKT *ptr = PUNKT(10,10);
// ptr jest wskazaniem (!!!) obiektu dynamicznego
żð tablicy obiektów i wskazania obiektu:
PUNKT tab[ 10 ], * ptr;
// elementy tablicy są konstruowane z użyciem konstruktora domyślnego
Niejednoznaczności
Mając zdefiniowaną poniższą klasę
class X
{
public:
X( void );
X( int j = 1);
};
i deklarujÄ…c obiekt X obj; stwarzamy dla kompilatora niejednoznacznÄ…
sytuację, ponieważ nie potrafi on stwierdzić, którego konstruktora ma
użyć: bezparametrowego, czy konstruktora z parametrem domyślnym.
14
Zasady używania list inicjacyjnych:
1. Obiekty będące składowymi innych klas oraz klasy bazowe mogą
być inicjowane tylko w liście inicjacyjnej
2. Składowe stałe i referencyjne mogą być inicjowane tylko w liście
inicjacyjnej.
Uwaga: Jeżeli obiekt nie ma zdefiniowanego jawnego konstruktora, może
być inicjowany wartościami innego obiektu tej samej klasy,
np. DATA d = dzisiaj;
Konstrukcja  podobiektów (obiektów składowych klasy)
Niech będzie dana klasa PUNKT_2D, której obiekty reprezentować będą
punkt na płaszczyżnie
class PUNKT_2D
{
int x, y;
public:
PUNKT_2D(void): x(0), y(0) { }
PUNKT_2D( int _x, int _y ): x( _x ), y( _y ) { }
int GetX( void ) {return x;}
int GetY( void ) {return y;}
};
oraz klasa
class ODCINEK
{
PUNKT_2D A, B;
// danymi składowymi klasy ODCINEK są dwa obiekty klasy
// PUNKT_2D
public:
ODCINEK(void) { }; // konstruktor 1
ODCINEK( int ax, int ay, int bx, int by): A( ax, bx), B( bx, by) { }
// konstruktor 2
15
ODCINEK( PUNKT_2D &A, PUNKT_2D &B): A( A ), B( B ) { }
// konstruktor 3 };
Przykłady poprawnych definicji obiektów:
PUNKT_2D A, B( 10, 10 );
ODCINEK O1( 10, 20, 110, 120 ), O2, O3( A, B);
Komentarze:
1. Obiekt O1 zostanie skonstruowany przy pomocy konstruktora
konstruktor 2 poprzez wywołania dwuparametrowych konstruktorów
klasy PUNKT_2D w celu skonstruowania podobiektów A i B.
2. Obiekt O2 zostanie skonstruowany przy pomocy konstruktora
bezparametrowego konstruktor 1. Ponieważ lista inicjacyjna tego
konstruktora jest pusta, kompilator przyjmie przez domniemanie, że
ma on postać ODCINEK(void): A( ), B( ) { } a co za tym idzie  do
inicjacji obiektów składowych A i B zostanie użyty konstruktor
domyślny klasy PUNKT_2D.
3. Obiekt O3 zostanie skonstruowany przy pomocy konstruktora
konstruktor 3. W typ przypadku obiekty składowe A i B zostaną
zainicjowane przez obiekty, będące parametrami konstruktora 3.
Konstruktory kopiujÄ…ce
Zadaniem konstruktorów kopiujących jest tworzenie obiektów z innych
obiektów tej samej klasy poprzez kopiowanie tych obiektów łącznie ze
strukturami zwiÄ…zanymi z obiektem.
Przykład:
class X
{ . . . . . . . .
public:
X(void); // konstruktor bezparametrowy (domyślny)
16
// poniżej deklaracja konstruktora kopiującego przez referencję
X( const X& );
// & i deklaracja konstruktora kopiujÄ…cego przez wskazanie
X( const X* );};
Poniżej przykłady poprawnego użycia konstruktorów zadeklarowanych w
klasie X:
X obj; // użyto konstruktora domyślnego
X obj1(obj); // użyto konstruktora kopiującego przez referencję
X obj2(&obj); // użyto konstruktora kopiującego przez wskazanie
Kwalifikator const zabezpiecza przed uszkodzeniem obiektu
kopiowanego, do którego konstruktor kopiujący uzyskuje dostęp przez
referencjÄ™, lub wskazanie.
Destruktory
class Y
{ . . . . . . . .
public:
Y(void); // konstruktor domyślny
~Y( void ); // destruktor
};
·ð Destruktor jest bezparametrowÄ… funkcjÄ… skÅ‚adowÄ… klasy, i jako
taki może być wywoływany na rzecz obiektu klasy powodując
zniszczenie (usunięcie) obiektu.
·ð Destruktor, oprócz usuniÄ™cia obiektu, powinien  posprzÄ…tać po
sobie , np. usunąć z ekranu okienko obsługujące obiekt, itp.
·ð Destruktory sÄ… najczęściej wywoÅ‚ywane w sposób niejawny.
Przykład delete Imie;
·ð JeÅ›li nie zdefiniowano destruktora jawnego kompilator wygeneruje
destruktor domyślny (zwykle nie sprząta po sobie).
17
Usuwanie obiektów automatycznych
Obiekty automatyczne (inaczej lokalne) to obiekty, które istnieją w
trakcie wykonywania się bloków instrukcji (między nawiasami {& } ).
Typowym blokiem jest ciało funkcji. Czas życia obiektu automatycznego
rozciąga się więc od momentu jego zadeklarowania w bloku do końca
bloku, pod warunkiem, że blok się wykonuje.
Przykład:
void f( int px, int py)
{ . . . . . . . . . . . . . . .
PUNKT_2D obP( px,py ); //obiekt obP jest położony na stosie
. . . . . . . . . . . . . . .
} //obiekt przestaje istnieć
Zakończenie wykonywania się, wywołanej wcześniej funkcji, spowoduje
bezwarunkowe (automatyczne) wywołanie destruktora (gdyby nie był
zdefiniowany  domyślnego) i usunięcie obiektu automatycznego obS.
Tworzenie i usuwanie obiektów dynamicznych
Przykład:
STRING * ptrP = new PUNKT_2D( 1, 0 );
delete ptrP; // wywołany zostanie destruktor
Czas życia obiektów dynamicznych rozciąga się od momentu ich
utworzenia (tutaj za pomocÄ… operatora new) do ich destrukcji
spowodowanej wywołaniem operatora delete.
Koniec części I


Wyszukiwarka

Podobne podstrony:
Jezyki i paradygmaty cz III
Jezyki i paradygmaty cz II
Jezyki i paradygmaty cz IV
Jezyki i paradygmaty cz V
Algorytmy i złożono ć zaocz cz I
Rozgrzewka po kwadracie – cz 2
sprzęt wędkarski cz 1
59 Języki świata bez odpowiedzi
Escherichia coli charakterystyka i wykrywanie w zywności Cz I
Deszczowa piosenka [cz 1]
07 GIMP od podstaw, cz 4 Przekształcenia
Wielka czerwona jedynka (The Big Red One) cz 2
Warsztat składamy rower cz 1

więcej podobnych podstron