Sposoby obejścia dziedziczenia Braki specyficznych rodzajów dziedziczenia można obejść wprowadzając dodatkowe: kompozycje asocjacje agregacje Każdy z tych związków reprezentuje się za pomocą atrybutów w klasach.
Sposoby obejścia dziedziczenia Najprostszy przypadek: kompozycja Kompozycję implementujemy poprzez umieszczenie odpowiedniego odnośnika wewnątrz klasy. SAMOCHÓD class Samochód { Silnik s; .... } SILNIK
Overlapping Overlapping – przecięcie zbiorów podklas nie jest zbiorem pustym. Pojazd { overlapping } Pojazd lądowy Pojazd wodny
Overlapping Obejście poprzez wprowadzenie dodatkowej klasy zawierającej sumę atrybutów innych podklas. Pojazd {disjoint, complete} Pojazd lądowy Pojazd wodny Pojazd wodno - lądowy
Overlapping Wady rozwiązania: konieczność tworzenia nowej klasy dla każdego pojazdu. dodawanie nowej klasy – pociąga za sobą tworzenie dużej ilości klas łączących poszczególne kategorie szybkie rozrastanie się hierarchii klas
Wielodziedziczenie (multi inheritance) Wielodziedziczenie – możliwość przejęcia inwariantów (pól i metod) z więcej niż jednej nadklasy. Występuje w języku C++, w Javie trzeba stosować rozwiązania zastępcze.
Przykład wielodziedziczenia Standardowa notacja UML: POJAZD { overlapping } POJAZD LĄDOWY POJAZD WODNY AMFIBIA
Wielodziedziczenie Jeżeli nie są wymagane szczegółowe informacje, można w ogóle zrezygnować z dziedziczenia. rezygnacja z podklas wprowadzenie dodatkowych atrybutów i metod POJAZD jezdzi() plywa()
Wielodziedziczenie Konstrukcja pozwalająca obejść brak wielodziedziczenia – zastąpienie przez kompozycję POJAZD Nazwa pojazdu 0..1 0..1 WŁAŚCIWOŚCI POJAZDU WODNEGO WŁAŚCIWOŚCI POJAZDU LĄDOWEGO Takie relacje pomiędzy klasami można zaimplementować w Javie.
Wielodziedziczenie – realizacja w Javie Wskazane jest, aby klasy Właściwości Pojazdu Lądowego i Właściwości pojazdu wodnego zostały zrealizowane jako klasy wewnętrzne klasy Pojazd. class Pojazd { String nazwa; WlPojLad wl; // może być null WlPojWod ww; // może być null class WlPojLad { double ladV; // predkosc na lądzie } class WlPojWod { double wodV; // predkosc w wodzie double wypornosc;
Wielodziedziczenie – realizacja w Javie Klasa Pojazd w tym przykładzie powinna być zaopatrzona w kilka konstruktorów w zależności od typu pojazdu. Pojazd(WlPojLad wl) { this.wl = wl; } Pojazd(WlPojWod ww) { this.ww = ww; Pojazd(WlPojLad wl, WlPojWod ww) {
Wielodziedziczenie – wady rozwiązania POJAZD POJAZD LĄDOWY POJAZD WODNY POJAZD POWIETRZNY Problemy pojawiają się gdy do istniejącej hierarchii klas dodajemy nową.
Wielodziedziczenie – wady rozwiązania w przypadku dodawania nowej podklasy (pojazd powietrzny) – konieczna modyfikacja kodu nadklasy class Pojazd { WlPojLad wl; WlPojWod ww; WlPojPow wp; class WlPojLad {...} class WlPojWod {...} class WlPojPow { .... } nowy odnośnik nowa klasa wewnętrzna
Wielodziedziczenie – wady rozwiązania Wady poprzedniego rozwiązania tzn. konieczność modyfikacji kodu już napisanych klas można obejść stosując następującą hierarchię: POJAZD WŁAŚCIWOŚCI POJAZDU WŁAŚCIWOŚCI POJAZDU LĄDOWEGO WŁAŚCIWOŚCI POJAZDU WODNEGO WŁAŚCIWOŚCI POJAZDU POWIETRZNEGO