Wstęp do programowania obiektowego
Wykład 1
Algorytmy i paradygmaty Podstawowe pojęcia PO
Cele przedmiotu
Zapoznanie z podstawowymi pojęciami oraz technikami programowania
obiektowego na przykładzie języka C++,
opanowanie projektowania,
implementacji i analizy programów w paradygmacie obiektowym.
Celem laboratorium jest opanowanie programowania obiektowego w języku C++.
Treści przedmiotu (1/2)
1. Powtórzenie materiału: algorytmy, podstawowe typy danych w języku C/C++, deklaracje zmiennych i stałych, wyrażenia i
instrukcje, funkcje, schematy blokowe.
2. Zmienne wskaźnikowe oraz pobranie adresu zmiennych i funkcji, przekazywanie parametrów do funkcji przez wartość i referencję, wskaźniki do funkcji, pliki.
3. Analiza dziedziny problemu, projektowanie obiektowe oraz programowanie obiektowe. Podejście strukturalne a podejście obiektowe do problemu.
4. Pojęcia klasy i obiektu. Składowe i metody. Schematy klas w UML. Zmienne statyczne. Składowe statyczne.
5. Tworzenie obiektów (konstrukcja, usuwanie, czas życia) w C++.
Treści przedmiotu (2/2)
6. Hermetyzacja składowych: kontrola dostępu. Przeciążanie metod i operatorów.
7. Dziedziczenie: dekompozycja problemu na hierarchie klas.
8. Polimorfizm. Rzutowanie w górę. Kompozycja. Schematy dziedziczenia i kompozycji w UML.
9. Dziedziczenie a kompozycja. Przesłanianie i widoczność składowych w dziedziczeniu.
10. Klasy abstrakcyjne. Metody wirtualne. Rozpoznawanie podtypów w trakcie wykonania.
11. Wielodziedziczenie.
12. Obsługa sytuacji specjalnych: wyjątki.
Literatura
OBOWIĄZKOWA:
1. Grębosz J., Symfonia C++ standard. Programowanie w języku C++ orientowane obiektowo, Edition 2000,
2. Stroustrup B., Język C++, WNT 1998.
UZUPEŁNIAJĄCA:
1. Lippman S.B., Istota języka C++. Zwięzły opis, WNT, 2004.
2. Vanderoorde D., Język C++ ćwiczenia i rozwiązania, WNT 2001.
3. Stasiewicz A., Ćwiczenia praktyczne C++, WNT,
Warunki zaliczenia
Prerekwizytem jest pozytywne zaliczenie laboratorium
Zaliczenie wykładu na podstawie egzaminu pisemnego, z następującą skalą ocen:.
3,0 - uzyskanie 50% maksymalnej liczby punktów,
3,5 - uzyskanie 60% maksymalnej liczby punktów,
4,0 - uzyskanie 70% maksymalnej liczby punktów,
4,5 - uzyskanie 80% maksymalnej liczby punktów,
5,0 - uzyskanie 90% maksymalnej liczby punktów.
ALGORYTMY I
PARADYGMATY
Pojęcie algorytmu
Algorytm - skończony, uporządkowany ciąg jasno zdefiniowanych czynności, koniecznych do wykonania pewnego rodzaju zadania.
Sposoby zapisu algorytmu
1. Najprostszy sposób: zapis słowny
2. Lista kroków
3. Zapis graficzny
Schematy blokowe
grafy (uproszczone schematy blokowe)
Sposoby zapisu algorytmu
1. Najprostszy sposób zapisu to zapis słowny
pozwala określić kierunek działań
2. Bardziej konkretny zapis to lista kroków
Zapisujemy kolejne kroki, które należy wykonać.
Budowa listy kroków:
sformułowanie zagadnienia (zadanie algorytmu)
określenie zbioru danych potrzebnych do rozwiązania zagadnienia (określenie czy zbiór danych jest właściwy)
określenie przewidywanego wyniku (wyników): co chcemy otrzymać i jakie mogą być warianty
rozwiązania
zapis kolejnych ponumerowanych kroków, które należy wykonać, aby przejść od punktu początkowego do
końcowego
1. Bardzo wygodny zapis to zapis graficzny
1. Schematy blokowe
blok operacji (prostokąt)
blok rozgałęzienia (romb)
blok we/wy (równoległobok)
bloki startu i stopu
2. grafy (uproszczone schematy blokowe)
Podział algorytmów ze względu na strukturę:
1 Algorytm liniowy
ciąg kroków, które są bezwarunkowo wykonane jeden po drugim.
nie zawiera żadnych warunków ani rozgałęzień: zaczyna się od podania zestawu danych, następnie wykonywane są kolejne kroki wykonawcze, aż dochodzimy do wyniku
2 Algorytm z rozgałęzieniem
zawiera rozgałęzienia będące efektem sprawdzania warunków.
Wyrażenia warunkowe umożliwiają wykonanie zadania dla wielu wariantów danych i rozważanie różnych przypadków.
3 Algorytm z powtórzeniami
pewne fragmenty kodu się powtarzają
a) liczba powtórzeń jest z góry określona (przed rozpoczęciem cyklu) - np. związany z działaniami na wektorach, macierzach
b) liczba powtórzeń jest nieznana (zależy od spełnienia pewnego warunku) - najczęściej związany z obliczeniami typu iteracyjnego
Pojęcie paradygmatu
Paradygmat:
[1] (w informatyce) zbiór mechanizmów, jakich programista używa, pisząc
program; i jak ten program jest następnie wykonywany przez komputer.
[2] (ogólnie) przyjęty sposób widzenia rzeczywistości w danej dziedzinie.
Programowanie imperatywne
Obliczenia rozumiemy tu jako sekwencję poleceń zmieniających krok po kroku stan maszyny, aż do uzyskania oczekiwanego wyniku.
Stan maszyny należy z kolei rozumieć jako zawartość całej pamięci oraz rejestrów i znaczników procesora.
Jest to ściśle związane z budową sprzętu
komputerowego o architekturze von Neumanna.
Architektura von Neumanna
Podział komputera na trzy podstawowe części:
procesor (ALU oraz CU)
pamięć komputera (Memory)
urządzenia wejścia/wyjścia (IN/OUT)
W najczystszym ujęciu program
imperatywny to algorytm liniowy, często jednak rozszerza się programowanie
imperatywne o struktury (rozgałęzienia i pętle) oraz procedury, co odpowiada
założeniom: programowania
strukturalnego oraz programowania proceduralnego.
Te trzy paradygmaty są do siebie bardzo zbliżone i bywają używane zamiennie.
Programowanie strukturalne
Programowanie strukturalne - paradygmat programowania zalecający hierarchiczne dzielenie kodu na bloki, z jednym punktem
wejścia i jednym lub wieloma punktami wyjścia.
Strukturalność zakłócają instrukcje typu: jump, goto, break, continue, które jednak niekiedy poprawiają czytelność kodu lub optymalizują wydajność programu.
Podstawowe struktury w
programowaniu strukturalnym
powtórzenia czyli pętle: while, do-while, for
rozgałęzienia/wybór: if, if-else, case, switch
Programowanie proceduralne
Programowanie proceduralne - paradygmat programowania zalecający dzielenie kodu na procedury, czyli fragmenty wykonujące ściśle określone operacje.
Procedury nie powinny korzystać ze
zmiennych globalnych (w miarę możliwości), lecz jawnie pobierać wszystkie potrzebne
dane (lub wskaźniki na potrzebne dane) jako parametry wywołania.
Programowanie Obiektowe
Programowanie Obiektowe (PO) jest
metodą projektowania i implementowania systemów informatycznych polegającą na modelowaniu obiektów rzeczywistych przy użyciu obiektów programowych.
Program obiektowy - to zbiór
porozumiewających się ze sobą obiektów, czyli jednostek zawierających pewne dane i umiejących wykonywać na nich pewne
operacje.
Koncepcja programowania obiektowego wydaje się inna od programowania
strukturalnego czy proceduralnego, w praktyce jednak mają one ze sobą wiele wspólnego:
◦ Programowanie obiektowe korzysta z
mechanizmów pr. strukturalnego, dodając jednocześnie obiektowe mechanizmy
składowania i przetwarzania danych.
Celem programowania obiektowego jest uproszczenie procesu programowania
(implementacji komputerowej rozwiązania jakiegoś problemu) przez wiązanie danych i procedur w hierarchiczne struktury oraz
wprowadzenie dodatkowych mechanizmów (np.
konstruktory, hermetyzacja, dziedziczenie, itp.).
Ma to ułatwić:
programowanie;
konserwację programów;
wielokrotne użycie programów lub ich fragmentów.
PODSTAWOWE POJĘCIA PROGRAMOWANIA
OBIEKTOWEGO
Pojęcia klasy i obiektu
Klasa - częściowa lub całkowita definicja pewnego zbioru obiektów o podobnych cechach.
Obiekt - pojedynczy przedmiot należący do pewnego zbioru obiektów (klasy) (tzw.
instancja klasy).
Przykład: definiujemy klasę Krzesło, która posiada następujące cechy: ilość nóg,
wysokość. Tworzymy obiekt o nazwie k2 klasy Krzesło, i nadajemy mu następujące wartości cech: ilość nóg=3, wysokość=55.
W języku C++, opis klasy jest dokonywany za pomocą pól (zmienne klasowe) i
metod (funkcje klasowe).
Definicja klasy w C++
Definicja klasy zawiera dwie części: nagłówek
składający się ze słowa kluczowego class, po którym następuje nazwa klasy oraz z ciała klasy
ograniczonego parą nawiasów klamrowych i zwykle zakończonego średnikiem.
class Punkt {
};
Jest to definicja pustej klasy Punkt.
Wewnątrz ciała klasy deklaruje się pola klasy (zwane też
zmiennymi składowymi lub właściwościami). Polami klasy mogą być różnego rodzaju typy danych (np. int, float, double, char, string, tablice, struktury oraz obiekty różnych klas).
class Punkt {
public:
int x; //pole typu int o nazwie x int y; //pole typu int o nazwie y };
Definicja funkcji w klasie
Aby zdefiniować funkcję klasową (tzw. metodę) należy ją dopisać do ciała klasy w postaci funkcji.
class Punkt {
public:
int x;
int y;
void przesuń_w_prawo(){
x = x+1;
} };
28
definicja funkcji w klasie
Deklaracja funkcji w klasie (definicja poza klasą)
Jeżeli definicja funkcji jest obszerna można ją przenieść poza klasę.
class Punkt { public:
int x;
int y;
void fun(void); // deklaracja funkcji fun()
};
void Punkt::void przesuń_w_prawo(){
x = x+1;
}
definicja funkcji poza klasą
Identyfikator dostępu
Aby jednoznacznie określić, która funkcja należy do
określonej klasy w C++ stosuje się identyfikator dostępu :: (czterokropek, złożony z dwóch dwukropków).
Funkcja zdefiniowana poza klasą ma więc postać:
void nazwa_klasy :: nazwa_funkcji(void) {
//definicja funkcji }
Tworzenie obiektów
To co było do tej pory napisane odnosiło się do klasy, czyli definicji (przepisu na
stworzenie) obiektu. Sam proces tworzenia obiektu nazywamy
instancjonowaniem.
Tworzenie obiektów dokonuje się tak
samo jak tworzenie zmiennych (statycznie lub dynamicznie).
ZMIENNE STATYCZNE I DYNAMICZNE W C++
Zmienne statyczne i dynamiczne
Zmienne statyczne Zmienne dynamiczne
Tworzone przy
pomocy: deklaracji zmiennych Funkcji malloc (C/C++) lub operatora new (C++)
Nazwa: posiadają nazwę nie posiadają nazwy
Dostęp: za pomocą nazwy
za pomocą powiązanego wskaźnika, który wskazuje
na zmienną
Dostęp do pól i metod obiektów
Do pól i metod obiektów statycznych odwołujemy się poprzez kropkę „.”
Do pól i metod obiektów dynamicznych odwołujemy się poprzez strzałkę „->”
(myślnik i znak większości)
Jest to analogiczne do odwoływania się do pól zmiennych strukturalnych (struct) statycznych i dynamicznych
34
Cykl życia zmiennych statycznych i dynamicznych
Etap Zmienne statyczne Zmienne dynamiczne
„zwykłe” „obiektowe” „zwykłe” „obiektowe”
0. Deklaracja
wskaźnika - - int *wsk; Punkt *wsk2;
1.Tworzenie int i; Punkt p1; wsk = new int; wsk2 = new Punkt;
2. Używanie printf(”%d”, i); i=5;
p1.x = 5;
printf(”%d”, p1.x);
*wsk = 5;
printf(”%d”, *wsk);
wsk2->x = 5;
printf(”%d”, wsk2-
>x);
class Punkt { public:
int x;
int y;
void przesuń_w_prawo() {x = x+2;}
};
main(void) {
Punkt p1; //obiekt stworzony statycznie p1.kolor=10; //odwołanie do pola przez kropkę
p1. przesuń_w_prawo(); // wywołanie metody przez kropkę
Punkt *wsk; //wsk – tworzenie wskaźnika na obiekt klasy Punkt
wsk = new Punkt; //stworzenie obiektu dynamicznego przy pomocy operatora new wsk->kolor=10; //odwołanie do pola przez ->
wsk-> przesuń_w_prawo(); //wywołanie metody przez ->
delete wsk; //usunięcie obiektu dynamicznego przy pomocy operatora delete }
36