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
SILNIK
class Samochód { Silnik s;
....
}
Overlapping
Overlapping – przecięcie zbiorów podklas nie jest zbiorem pustym.
Pojazd
Pojazd
lądowy Pojazd
wodny
{ overlapping }
Overlapping
Pojazd
Pojazd
lądowy Pojazd
wodny
{disjoint, complete}
Pojazd wodno - lądowy
Obejście poprzez wprowadzenie dodatkowej klasy zawierającej sumę atrybutów innych podklas.
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 – możliwość przejęcia inwariantów (pól i metod) z więcej niż jednej nadklasy.
Wielodziedziczenie (multi inheritance)
Występuje w języku C++, w Javie trzeba stosować rozwiązania zastępcze.
Przykład wielodziedziczenia
Standardowa notacja UML:
POJAZD
POJAZD LĄDOWY
POJAZD WODNY
AMFIBIA
{ overlapping }
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
POJAZD
Nazwa pojazdu
WŁAŚCIWOŚCI POJAZDU LĄDOWEGO
WŁAŚCIWOŚCI POJAZDU WODNEGO
Konstrukcja pozwalająca obejść brak wielodziedziczenia – zastąpienie przez kompozycję
0..1 0..1
Takie relacje pomiędzy klasami można zaimplementować w
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) { this.wl = wl;
this.ww = ww;
}
Wielodziedziczenie – wady rozwiązania
POJAZD
POJAZD LĄDOWY
POJAZD WODNY
POJAZD
POWIETRZNY
Problemy pojawiają się gdy do istniejącej hierarchii klas dodajemy nową.
• w przypadku dodawania nowej podklasy (pojazd powietrzny) – konieczna modyfikacja kodu nadklasy
Wielodziedziczenie – wady rozwiązania
class Pojazd { WlPojLad wl;
WlPojWod ww;
WlPojPow wp;
class WlPojLad {...}
class WlPojWod {...}
class WlPojPow { ....
}
nowa klasa wewnętrzna nowy odnośnik
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