290 likes | 480 Views
Projektowanie systemów informacyjnych. Wykład 2: Wprowadzenie do obiektowości, cz. 2. Kazimierz Subieta Instytut Podstaw Informatyki PAN, Warszawa Polsko-Japońska Wyższa Szkoła Technik Komputerowych, Warszawa. Wprowadzenie do obiektowości, cz. 2. Klasy Metody
E N D
Projektowanie systemów informacyjnych Wykład 2: Wprowadzenie do obiektowości, cz. 2 Kazimierz Subieta Instytut Podstaw Informatyki PAN, Warszawa Polsko-Japońska Wyższa Szkoła Technik Komputerowych, Warszawa
Wprowadzenie do obiektowości, cz. 2 • Klasy • Metody • Przesłanianie, przeciążanie • Ekstensja • Typ, abstrakcyjny typ danych • Własność zastępowania • Hermetyzacja • Dziedziczenie • Delegacja, prototypy • Późne wiązanie • Wielokrotne dziedziczenie
Klasa class Dwa rozumienia, które nie zawsze są ze sobą zgodne: 1. Klasa jest nazwanym zbiorem obiektów o podobnych własnościach. Własności te (zestaw atrybutów, metody) są określone w definicji klasy. Stosunek klasa/podklasa oznacza zawieranie się zakresów znaczeniowych. Np. zbiór obiektów Student zawiera się w zbiorze obiektów Osoba. 2. Klasa jest miejscem przechowywania cech grupy obiektów, które są niezmienne (inwariantów). Klasa nie jest zbiorem obiektów i niekoniecznie jest definicją zbioru obiektów. Stosunek klasa/podklasa oznacza, że obiekty podklasy posiadają wszystkie inwarianty nadklasy, plus swoje inwarianty. Np. klasa Student ma wszystkie inwarianty klasy Osoba, plus niektóre własne. Nazwa, czyli językowy identyfikator obiektu Typ, czyli statyczna budowa obiektu (atrybuty) Metody, czyli operacje, które można wykonać na obiekcie Najważniejsze inwarianty to: Zdarzenia lub wyjątki, które mogą zajść w operacjach na obiekcie Obsługa zdarzeń lub wyjątków (reguły aktywne) Lista eksportowa, określająca, które atrybuty dostępne są z zewnątrz Ograniczenia, którym musi podlegać każdy obiekt ...... Możliwe są inne inwarianty:
Numer: 123-4321 Stan konta: 34567 PLN Właściciel: Jan Kowalski Upoważniony: .... Wypłać Wpłać Porównaj podpis Sprawdź stan Numer: 999-9999 Stan konta: integer Właściciel: string Upoważniony:.... .... Nalicz procent Zlikwiduj konto Numer: 123-4567 Stan konta: 454545 PLN Właściciel: Adam Nowak Upoważniony: .... Zmień upoważnienie Upoważnij Metody jako inwarianty klasy methods Zwykle, istnieje wiele bardzo podobnych obiektów: konto, książka, pracownik, ,.... Nie byłoby zbyt celowe, aby każdy z takich obiektów przechowywał w sobie własną kopię metod lub informacji o swoim typie. Ta informacja jest przechowywa raz w ramach klasy. Klasa wszystkich kont Obiekty KONTO import inwariantów
OSOBA NAZWISKO ROK_UR Wiek() STUDENT NR_INDEKSU WYDZIAŁ WstawOcenę(...) ZaliczSemestr() Podklasa, nadklasa subclass, superclass Klasy mogą tworzyć hierarchię lub inną strukturę bez pętli. Import inwariantów do obiektów (w szczególności, atrybutów i metod) jest tranzytywny. GRAFIKA ROZMIAR Wyświetl(...) JPEG GIF PRACOWNIK ZAROBEK DZIAŁ FOTO ZarobekNetto() ZmieńZarobek(...) Atrybut PRACOWNIKa FOTO należy do własnej klasy. Generalnie, struktura klas może być semantycznie bardziej złożona niż hierarchia.
Klasa abstrakcyjna, klasa konkretna abstract class, concrete class Klasa abstrakcyjna nie ma (nie może mieć) wystąpień i służy wyłącznie jako nadklasa dla innych klas. Klasa abstrakcyjna może zawierać abstrakcyjne operacje, tj. opis operacji, ale nie implementacje. Klasa konkretna może mieć wystąpienia konkretnych obiektów. Klasa konkretna może zawierać implementacje abstrakcyjnych operacji. Sekwencja pierwszy następny Osoba prawna Klasyczne klasyfikacje w biologii: tylko liście w drzewie klas mogą być klasami konkretnymi. Osoba fizyczna Firma Sekwencja int ... implementacje Sekwencja char ...implementacje
Pracownik nazwisko ... zwolnij() ... Samodzielny prac.naukowy zwolnij() Przesłanianie overriding Atrybut lub metoda z klasy bardziej szczegółowej “zasłania” atrybut lub metodę z klasy bardziej ogólnej Decyzja o zwolnieniu w gestii dyrekcji Decyzja o zwolnieniu w gestii sekretariatu PAN Metody są różne, choć mają tę samą nazwę.
Przeciążanie overloading, static polymorphism Pojęcie podobne do przesłaniania. Oznacza, że jakiś symbol (np. operatora, funkcji, porównania) ma znaczenie zależne od kontekstu jego użycia, np. od składni lub ilości/typu argumentów. Powszechne jest przeciążanie operatora równości: = służy do porównania liczb całkowitych, liczb rzeczywistych, stringów, identyfikatorów, struktur, itd. Podobnie, operator + może oznaczać dodawanie lub konkatenację. Przeciążanie nie wymaga dynamicznego wiązania: znaczenie operatora, mimo że homonimiczne, można wydedukować na podstawie statycznej analizy tekstu programu. W odróżnieniu, przesłanianie jest własnością dynamiczną, nie zawsze da się wydedukować z tekstu programu.
Niektóre metody zawarte w ramach klasy odnoszą się do jej wystąpień: pracownik.wiek pracownik.zwolnij KONTO.Oblicz_procent Wystąpienie, ekstensja instance, extent Wystąpienie klasy (class instance, class member, class occurence) = obiekt który jest podłączony do danej klasy (jest “członkiem”). Na ogół taki obiekt przechowuje tylko wartości jego atrybutów; reszta informacji jest zawarta w ramach jego klasy. Ekstensja klasy (class extent) = aktualny (zmienny w czasie) zestaw wszystkich wystąpień tej klasy. Klasa może mieć nie jedno lecz wiele ekstensji. Niektóre metody zawarte w ramach klasy odnoszą się do jej ekstensji: KL_pracownik.nowy KL_pracownik.zlicz KL_KONTO.Oblicz_sumę
Typ type Typ obiektu określa jego formalną budowę (atrybuty) oraz ogranicza kontekst, w którym odwołanie do obiektu może być użyte w programie. W wielu opracowaniach i językach (C++, Eiffel) typ utożsamia się z klasą. Wielu autorów uważa jednak te dwa pojęcia za różne. Klasa: przechowalnia inwariantów, implementacja metod. Typ: specyfikacja budowy obiektu, specyfikacja metod. Podstawowe zastosowanie klasy: modelowanie pojęciowe. Podstawowe zastosowanie typu: statyczna kontrola poprawności programów Generalnie, na linii rozróżnień definicyjnych pomiędzy pojęciami: • klasa (class) • typ (type) • abstrakcyjny typ danych(abstract data type, ADT) • ekstensja (extent) panuje spore zamieszanie.
Abstrakcyjny typ danych abstract data type, ADT Pojęcie udostępniane w niektórych językach programowania oparte na założeniu, że typ struktury danych jest skojarzony z operacjami działającymi na elementach tego typu. Nie istnieje potrzeba i możliwość używania operacji nie należących do oferowanego zestawu; operacje są kompletne i wyłączne (patrz hermetyzacja). Bezpośredni dostęp do składowych takiej struktury danych nie jest możliwy. Abstrakcyjny typ danych jest bardzo bliski pojęciu klasy, której wystąpienia eksportują (niektóre) operacje, zaś ich struktura jest niedostępna dla operacji z zewnątrz. ADT nie wyznacza typu konkretnego (tj. budowy obiektu), ale ogranicza kontekst, w którym odwołanie do obiektu może być użyte w programie. ADT może odnosić się nie tylko do obiektów, ale również do wartości. Np. definiujemy typ abstrakcyjny KameraWideo z operacjami: Włącz, Wyłącz, Nagrywaj, Stop, Bliżej, Dalej, PrzewińWTył, Odtwarzaj, ... Zestaw tych operacji jest stosunkowo nieliczny, natomiast wewnętrzna budowa obiektu jest bardzo złożona (zawiera tysiąceatrybutów), ale niezbyt interesująca z punktu widzenia operacji zewnętrznych.
Typy masowe bulk types Typy, dla których rozmiar wartości nie da się przewidzieć ani sensownie ograniczyć. Kolekcje (terminologia ODMG-93): Zbiory (sets): kolekcja elementów dowolnego typu, ale bez powtórzeń. Wielo-zbiory (multisets, bags): kolekcje elementów dowolnego typu, elementy mogą się powtarzać. Sekwencje (sequences): uporządkowane kolekcje elementów dowolnego typu; porządek ma znaczenie informacyjne, elementy mogą się powtarzać. Tablice dynamiczne (dynamic arrays): sekwencje, ale z dostępem poprzez indeks. Ortogonalność konstruktorów typu: typy masowe mogą być dowolnie kombinowanez dowolnymi innymi typami, np. zbiór sekwencji; obiekt, którego atrybutami są wielo-zbiory, itd. Popularne języki obiektowe nie mają typów masowych lub je ograniczają (Smalltalk, C++). Systemy przed-obiektowe nie są zgodne z zasadą ortogonalności konstruktorów typu.
Mocna kontrola typu (1) strong type checking, strong typing Każdy byt programistyczny (obiekty, zmienne, procedury, funkcje, metody, operacje, moduły, klasy, ADT) podlega obowiązkowej specyfikacji typu. Każda operacja w programie jest sprawdzana na zgodność z specyfikacją typu. Statyczna kontrola typu: kontrola tekstu programu (podczas kompilacji). Dynamiczna kontrola typu: kontrola typów podczas czasu wykonania. • Zwykle mocna kontrola typu oznacza kontrolę statyczną. • Kontrola dynamiczna jest znacznie mniej skuteczna, z dwóch powodów: • jest istotnym obciążeniem czasu wykonania • błąd typu podczas wykonania jest takim samym błędem jak każdy inny, • a rakieta przecież jest już w locie... Z drugiej strony, mocna statyczna kontrola typu powoduje znaczne zmniejszenie mocy języka programowania i jego elastyczności. (Np. jak napisać procedurę w Pascal’u, która mnoży dwie macierze o dowolnych rozmiarach?) Własności takie jak: późne wiązanie, wartości zerowe, warianty, perspektywy, procedury bazy danych, dynamiczne klasy, etc. wymagają kontroli dynamicznej.
Podtyp subtype Dwie definicje: Ekstensja podtypu jest podzbiorem ekstensji typu. Np. liczba naturalna (1,2,...) jest podtypem typu liczba całkowita (...,-2,-1,0,1,2,...). Typ A jest podtypem typu B, jeżeli A zawiera więcej atrybutów (operacji, metod,...) niż B. A < B < struct Pracownik( string Nazwisko, int Rok_urodz, int Zarobek ) Pracownik jest podtypem Osoba struct Osoba ( string Nazwisko, int Rok_urodz ) Pojęcie podtypu staje się bardziej złożone w przypadku procedur, funkcji i metod. Kiedy typ funkcji A jest podtypem typu funkcji B? (Warunki na typy parametrów dla obu funkcji oraz na typy ich wyników.) Innym (równoważnym) punktem widzienia na kwestię podtypowania jest założenie, że każdy obiekt może mieć wiele typów (swojej klasy podstawowej i wszystkich jej superklas).
Własność zastępowania substitutability Podstawowa zasada kontroli typów w obiektowości: Jezeli w jakimś miejscu programu (zapytania,...) może być użyty typ A, to może tam byc także użyty dowolny podtyp typu A. Jezeli w jakimś miejscu programu może być użyta liczba całkowita, to może być tam także użyta liczba naturalna. Jeżeli w jakimś miejscu programu może być użyty obiekt Osoba, to w tym samym miejscu może być użyty obiekt Pracownik. Zasada ta wydaje się oczywista, ale niekiedy powoduje anomalie:
Rozszerzalność systemu typów type system extensibility • Projektant ma do wyboru wiele konstruktorów typu (ortogonalna kombinacja). • Nowy typ można zdefiniować na podstawie typu już istniejącego. Konstruktorzy typów: • typy atomowe: character, integer, float, string, boolean, bitmap, ... • typy zapisów (records): struct(nazwa:string, waga:float) • zbiory (sets): set of bitmap, set of struct(nazwa:string, waga:float) • tablice (arrays): array of integer, array[5..30] of set of bitmap • wielozbiory (bags): zbiory z powtórzeniami • sekwencje (sequences): wielozbiory uporządkowane • ..... (jest jeszcze trochę mniej istotnych możliwości) Definicja nowego typu na podstawie typu już zdefiniowanego: istotna możliwość ponownego użycia. TypCzęści = struct(string nazwa, float waga); TypRelacjiCzęści = set of TypCzęści; TypCzęściKolorowej is TypCzęści {string kolor} podtyp
Hermetyzacja, ukrywanie informacji encapsulation, information hiding Hermetyzacja: zgromadzenie elementów struktury i implementacji obiektu w postaci jednej manipulowalnej bryły; oddzielenie specyfikacji obiektu od jego implementacji. Hermetyzacja oznacza takżeukrycie części struktury i implementacji obiektu. Tę własność określa się jako ukrywanie informacji. Hermetyzacja i ukrywanie informacji są różnymi pojęciami, ale mocno powiązanymi. Zasada inżynierii oprogramowania (Parnas, 1972): programista ma tyle wiedzieć o obiekcie programistycznym, ile mu trzeba, aby go efektywnie użyć. Wszystko, co może być przed nim ukryte, powinno być ukryte. Hermetyzacja i ukrywanie informacji jest podstawą pojęć modułu, klasy i ADT. Hermentyzacja ortogonalna (C++) Hermetyzacja ortodoksyjna (Smalltalk) Dowolna własność obiektu (atrybut, metoda,...) może być prywatna (ukryta) lub publiczna Na zewnątrz są widoczne metody; atrybuty obiektu są ukryte. Ergo: prawie każdy atrybut atr jest obsługiwany przez dwie metody: czytaj_atr, zmień_atr Specjalne środki do specyfikowanie własności prywatnych i publicznych.
Hermetyzacja ortogonalna Patrz Modula-2: dowolna własność może być prywatna, lub może być “wyeksportowana” do publicznego użytku. PRAC NAZWISKO Nowak ROK_UR 1951 Wewnętrzna struktura obiektu ZAROBEK 2500 DZIAŁ Zabawki ZarobekNetto() ZmieńZarobek(...) Podatek() Wiek() begin return RokBież() - ROK_UR end; PRAC NAZWISKO Nowak ROK_UR 1951 ZAROBEK 2500 DZIAŁ Zabawki Zewnętrzna struktura obiektu Podatek() ZarobekNetto() ZmieńZarobek(...) Wiek() begin return RokBież() - ROK_UR end; Wiek()
OSOBA NAZWISKO ROK_UR OSOBA NAZWISKO ROK_UR Dziedziczenie (1) inheritance • Dziedziczenie umożliwia: • zdefiniowanie nowej, bardziej wyspecjalizowanej klasy na podstawie klasy • już istniejącej. • automatyczny import wszystkich inwariantów (opisu atrybutów, metod, etc.) • z klas bardziej ogólnych do klas wyspecjalizowanych. Klasa wyspecjalizowana Klasa ogólna PRACOWNIK NAZWISKO ROK_UR ZAROBEK DZIAŁ PRACOWNIK ZAROBEK DZIAŁ
OSOBA NAZWISKO ROK_UR Wiek() PRACOWNIK ZAROBEK DZIAŁ ZarobekNetto() ZmieńZarobek(...) PRACOWNIK NAZWISKO: Nowak ROK_UR: 1951 ZAROBEK: 2000 DZIAŁ: zabawki PRACOWNIK NAZWISKO: Nowacki ROK_UR: 1940 ZAROBEK: 3000 DZIAŁ: sprzedaż PRACOWNIK NAZWISKO: Abacki ROK_UR: 1948 ZAROBEK: 2500 DZIAŁ: zabawki Dziedziczenie (2) Ekstensja OSOBA OSOBA NAZWISKO: Kowalska ROK_UR: 1975 OSOBA NAZWISKO: Nowak ROK_UR: 1951 OSOBA NAZWISKO: Abacki ROK_UR: 1948 OSOBA NAZWISKO: Nowacki ROK_UR: 1940 Ekstensja PRACOWNIK
Lista pierwszy następny ostatni dodaj usuń Stos push pop Delegacja delegation Operacje na obiekcie są oddelegowane do innego obiektu. Stos zawartość push pop Obiekt “Stos” składa się z pod-obiektu “zawartość”, który z kolei dziedziczy operacje z klasy “Lista”. Anomalia dziedziczenia jest usunięta. Obsługa obiektu Stos jest (częściowo) oddelegowana do (pod) obiektu Lista. Lista pierwszy następny ostatni dodaj usuń Delegacja: alternatywa dla dziedziczenia. Dziedziczenie w ramach wystąpień obiektów, dziedziczenie dynamiczne. Część własności danego obiektu (np. metody) jest przechowywana w innym obiekcie. Obiekt “Stos” niepotrzebnie dziedziczy operacje z klasy “Lista”
Kot Pies Wabi_się: Mrusia Wabi_się: Rex Rasa: nieznana Rasa: jamnik Płeć: Ż Płeć: M Uszy:1 Prototypy prototypes Pojęcie ściśle powiązane z delegacją. Języki prototypowe (np. Self) nie wprowadzają pojęcia klasy. Obiekt może dziedziczyć cokolwiek z jakiegokolwiek innego obiektu. Podstawowym argumentem zwolenników prototypów jest zmniejszenie liczby pojęć. Koncepcja prototypów jest nieunikniona, jeżeli ktoś chciałby implementować dynamiczne role obiektów. Pojęcie klasy ma jednak ogromne znaczenie dla modelowania pojęciowego, stąd pojęcia prototypu i klasy uzupełniają się. Ulubieniec Łapy: 4 Ogon: 1 Uszy:2 Oczy:2 Szczepienie() Prototyp
Dynamiczne (poźne) wiązanie dynamic (late) binding Wiązanie (binding) - zamiana identyfikatora symbolicznego występującego w programie (tj. nazwy) na wartość, adres lub wewnętrzny identyfikator elementu programistycznego (danej, zmiennej, procedury,...) Wczesne (statyczne) wiązanie:przed uruchomieniem programu, podczas kompilacji i konsolid. Zalety: szybkość działania programu, możliwość pełnej statycznej kontroli typów Wady: słaba możliwość komponowania programu z niezależnych składowych, brak możliwości rozbudowy aplikacji podczas jej działania Późne (dynamiczne) wiązanie: w czasie wykonania programu. Zalety: możliwość dynamicznego przesłaniania i polimorfizmu, możliwość komponowania programu z niezależnych składowych, szybkie przechodzenie od nowego pomysłu do efektu Wady: wolniejsze działanie programu, utrudniona kontrola typów • Późne wiązanie jest nieodzownym warunkiem dla: • implementacji komunikatów (polimorfizmu) • dynamicznie tworzonych perspektyw • dynamicznie tworzonych procedur bazy danych • języków zapytań • migracji obiektów • ewolucji schematu BD
Osoba Nazwisko Student Pracownik Nr_indeksu Zarobek Pracujący_ student Wielokrotne dziedziczenie multiple inheritance, multi-inheritance Obiekt dziedziczy inwarianty z więcej niż jednej klasy, które nie są zależne Aga Kazio Jola Krzyś Adam Basia Kasia
Problemy wielokrotnego dziedziczenia Pojazd ..... prędk_eksploat() Np. prędkość eksploatacyjna wynosi 50% prędkości maksymalnej Pojazd lądowy max_prędkość ..... Pojazd wodny max_prędkość ..... Samochód Amfibia Jacht Konflikt nazw: Który atrybut max_prędkość ma odziedziczyć amfibia? Czy znaczenie metody prędk_eksploat() zależy od ścieżki dziedziczenia? (O2: mechanizm zmiany nazwy dziedziczonej cechy; Eiffel: konflikt jest traktowany jako błąd.) Kontrola typu: Jaki będzie wynikowy typ obiektów Amfibia? Najczęściej wielo-dziedziczenie jest konsekwencją braku koncepcji ról
Role Osoba staje się Studentem Źle! Student jest Osobą Każdy obiekt w czasie swojego życia może nabywać i tracić wiele ról, nie zmieniając swojej tożsamości. Role zmieniają się dynamicznie. Osoba Kowalski Właściciel psa Członek klubu golfowego Kibic Legii Podatnik Pacjent Student Pracownik • Rola importuje wartości atrybutów obiektu • oraz dziedziczy inwarianty jego klasy • Rola może mieć własne (dodatkowe) atrybuty • Rola może należeć do własnej klasy
OSOBA NAZWISKO ROK_UR Wiek() STUDENT NR_INDEKSU INDEKS WpiszOcenę(...) ObliczŚredniąOcen() PRACOWNIK ZAROBEK: 2500 DZIAŁ: zabawki PRACOWNIK ZAROBEK: 2000 DZIAŁ: zabawki STUDENT NR_INDEKSU:223344 INDEKS:...... STUDENT NR_INDEKSU:556677 INDEKS:...... Role - przykład Kowalska: pracownik Nowak: pracownik+student Abacka: Nowacki: student OSOBA NAZWISKO: Kowalska ROK_UR: 1975 OSOBA NAZWISKO: Nowak ROK_UR: 1951 OSOBA NAZWISKO: Abacka ROK_UR: 1948 OSOBA NAZWISKO: Nowacki ROK_UR: 1940 PRACOWNIK ZAROBEK DZIAŁ ZarobekNetto() ZmieńZarobek(...) Rola dziedziczy nie tylko inwarianty swojej klasy, lecz także wartości atrybutów swojego obiektu i inwarianty jego klasy.
Podsumowanie Obiektowość jest nową ideologią, która zmienia myślenie realizatorów SI z “zorientowanego na maszynę” na “zorientowane na człowieka”. Obiektowość jest konsekwencją kryzysu oprogramowania: kosztów związanych z oprogramowaniem, jego zawodnością, i trudną do opanowania złożonością. Obiektowość przenika wszelkie fazy projektowania, oraz narzędzia i interfejsy. Obiektowość dopracowała się własnej kolekcji pojęć i narzędzi. Obiektowość jest na początku swojej drogi i musi walczyć z konserwą i spuścizną poprzednich ideologii.