Dziedziczenie

39
Dziedziczenie Marek Serek 132822

description

Dziedziczenie. Marek Serek 132822. Dziedziczenie. Dziedziczenie to jeden z fundamentów programowania obiektowego. Umożliwia sprawne i łatwe wykorzystywanie już raz napisanego kodu czy budowanie hierarchii klas, przejmujących swoje właściwości. Klasy potomne. - PowerPoint PPT Presentation

Transcript of Dziedziczenie

Page 1: Dziedziczenie

Dziedziczenie

Marek Serek 132822

Page 2: Dziedziczenie

Dziedziczenie

Dziedziczenie to jeden z fundamentów programowania obiektowego. Umożliwia sprawne i łatwe wykorzystywanie już raz napisanego kodu czy budowanie hierarchii klas, przejmujących swoje właściwości.

Page 3: Dziedziczenie

Klasy potomne

W tej części zostaną przedstawione podstawy dziedziczenia, czyli budowanie nowych klas na bazie już istniejących. Każda taka klasa przyjmuje zachowanie i właściwości klasy bazowej. Zobaczymy, jak tworzy się klasy potomne, jakie podstawowe zależności występują miedzy klasą bazową, a potomną oraz jak zachowują się konstruktory w przypadku dziedziczenia.

Page 4: Dziedziczenie

Dziedziczenie

Załóżmy, że mamy stworzoną klasę Punkt, która przechowuje informacje o współrzędnej punktu na płaszczyźnie i która posiada dodatkowe metody, które pozwalają na ustawienie i pobranie tych współrzędnych. Zastanówmy się teraz co byśmy zrobili, gdybyśmy potrzebowali określać położenie punktu nie w dwóch, ale w trzech wymiarach, czyli do współrzędnych x i y trzeba było dodać współrzędną z.

Page 5: Dziedziczenie

Dziedziczenie

Pomysł który się od razu nasuwa, jest napisanie dodatkowej klasy, np. o nazwie Punkt3D, w postaci:

class Punkt3D{int x;int y;int z;}Do tej klasy należałoby dalej dopisać zestaw metod,

które znajdowały się w klasie Punkt, takich jak pobierzX, pobierzyY, ustawX, ustawY itd. Oraz dodatkowe metody operujące na współrzędnej z.

Page 6: Dziedziczenie

Dziedziczenie

Aby się nie powtarzać w już raz napisanym kodzie należy zastosować dziedziczenie.Ponieważ klasa Punkt3D jest pewnego rodzaju rozszerzeniem klasy Punkt. Rozszerza je o dodatkowe możliwości (pola, metody) pozostawiając stare właściwości bez zmian. Zamiast więc pisać całkiem od nowa klasę Punkt3D lepiej spowodować, aby przejęła ona wszystkie możliwości klasy Punkt, wprowadzając dodatkowo swoje własne pola i metody. Powiemy wówczas, że klasa Punkt3D dziedziczy z klasy Punkt, czyli przejmuje jej pola i metody oraz dodaje swoje własne.

Page 7: Dziedziczenie

Dziedziczenie

W Javie dziedziczenie jest wyrażone za pomocą słowa extends, a cała definicja schematycznie wygląda następująco:

class klasa_potomna extends klasa_bazowa{//ciało klasy}

Zapis taki oznacza, że klasa potomna dziedziczy z klasy bazowej.

Page 8: Dziedziczenie

Przykład

Page 9: Dziedziczenie

Dziedziczenie

Klasa Punkt3D, dziedziczy z klasy Punkt dwa pola x i y oraz wszystkie metody: pobierzX , pobierzY, ustawX, ustawY. Oprócz tego zawiera własne pole z i dwie metody pobierzZ i ustawZ.

Page 10: Dziedziczenie

Konstruktory klasy bazowej i potomnej

Klasa Punkt3D posiada już metody operujące na polu z, tzn. ustawiające oraz pobierające jego wartość, brakuje jej jednak konstruktorów. Przypomnijmy, że w klasie Punkt napisaliśmy aż trzy konstruktory:

• Bezparametrowy, ustawiający wartość wszystkich pól na 1

• Dwuparametrowy, przyjmujący dwie wartości typu int

• Jednoparametrowy, przyjmujący obiekt klasy Punkt

Page 11: Dziedziczenie

Konstruktory klasy bazowej i potomnej

Konstruktory dla klasy Punkt3D musimy wiec napisać sami.

Page 12: Dziedziczenie

Konstruktory klasy bazowej i potomnej

Jeśli przyjrzymy się dokładnie napisanym przed chwilą konstruktorom, zauważymy, że w znacznej części ich kod dubluje się z kodem konstruktorów klasy Punkt.

Page 13: Dziedziczenie

Konstruktory klasy bazowej i potomnej

Lepiej będzie zatem wykorzystać konstruktor klasy Punkt w klasie Punkt3D lub ogólniej konstruktor klasy bazowej w konstruktorze klasy potomnej. Do tego celu służy specjalna konstrukcja. Dokładniej w konstruktorze klasy potomnej należy wywołać metodę super()

Page 14: Dziedziczenie

Konstruktory klasy bazowej i potomnej

Jeśli metodzie super przekażemy parametry, zostanie wywołany konstruktor klasy bazowej, który tym parametrom odpowiada. Do praktycznego zobrazowania takiej konstrukcji doskonale nadaje się klasa Punkt3D.

Page 15: Dziedziczenie

Specyfikatory dostępu i pakiety

Specyfikatory dostępu pełnią ważna rolę w Javie, pozwalają bowiem na określenie swoistego rodzaju praw dostępu do składowych klas, a także do samych klas.

W Javie przed każdym polem i metodą może, a czasami nawet powinien, pojawić się tak zwany specyfikator dostępu.

Page 16: Dziedziczenie

Publiczne, prywatne czy chronione?

Dostęp do każdego pola i każdej metody może być:

• publiczny,• prywatny,• chroniony,• pakietowy.

Page 17: Dziedziczenie

Publiczne, prywatne czy chronione?

Domyślnie, jeżeli przed składową klasy nie występuje żadne określenie, dostęp jest pakietowy, co oznacza, że dostęp do tej składowej mają wszystkie klasy pakietu, w którym się one znajdują. Dostęp publiczny jest określony słowem public, dostęp prywatny słowem private, a dostęp chroniony słowem protected.

Page 18: Dziedziczenie

Dostęp prywatny - private

Składowe oznaczone słowem private to takie, które są dostępne jedynie z wnętrza danej klasy. To oznacza, że wszystkie metody danej klasy mogą je dowolnie odczytywać i zapisywać, natomiast żadna inna klasa nie może ani ich odczytać, ani zapisać. Dla innych klas są po prostu niewidoczne.

Należy pamiętać że składowe prywatne nie będą dostępne nawet dla klas potomnych.

Page 19: Dziedziczenie

Przykład

Page 20: Dziedziczenie

W jaki sposób się odwołać do pola prywatnego?

Aby odwołać się do pola prywatnego wystarczy zatem, jeśli napiszemy publiczne metody pobierające i ustawiające pola prywatne. Wtedy będziemy mogli wykonywać na nich operacje.

Page 21: Dziedziczenie

Dostęp chroniony - protected

Składowe klasy oznaczone słowem protected to składowe chronione. Są one dostępne jedynie dla metod danej klasy, klas potomnych oraz klas z tego samego pakietu. Oznacza to, że jeśli mamy przykładową klasę Punkt, w której znajdzie się chronione pole o nazwie x, to w klasie pochodnej Punkt3D, również będziemy mogli odwoływać się do pola x. Jednak dla każdej innej klasy, która nie dziedziczy z Punkt, pole x będzie niedostępne.

Page 22: Dziedziczenie

Czemu ukrywamy wnętrze klasy?

Zabraniamy bezpośredniego dostępu do niektórych składowych klas, stosując modyfikatory private i protected, aby ukryć implementacje wnętrza klasy. Programista, projektując daną klasę udostępnia na zewnątrz (innym programom) pewien interfejs służący do posługiwania się obiektami tejże klasy.

Page 23: Dziedziczenie

Czemu ukrywamy wnętrze klasy?

Czyli określa sposób, w jaki można korzystać z danego obiektu. To co znajduje się wewnątrz, jest ukryte, dzięki temu można całkowicie zmienić wewnętrzną konstrukcję klasy, nie zmieniając zupełnie sposobu korzystania z niej.

Page 24: Dziedziczenie

Przeciążenia metody a dziedziczenie

Przeciążenie metod, czyli możliwość umieszczenia w jednej klasie kilku metod o tej samej nazwie, różniących się argumentami. Pytanie, jak ma się to do dziedziczenia, czyli czy możemy przeciążać metody klasy bazowej w klasie potomnej? Odpowiedź brzmi-tak. Jeśli mamy np.. Klasę o nazwie A, a w niej bezargumentową metodę f, czyli klasę w postaci:

Page 25: Dziedziczenie

Przeciążenia metody a dziedziczenie

I z tej klasy wyprowadzimy klasę pochodną o nazwie B, to w klasie B możemy zdefiniować przeciążoną metodę f, np. przyjmującą jeden typ int.

Page 26: Dziedziczenie

Przeciążenia metody a dziedziczenie

Czyli w klasie A została zdefiniowana bezargumentowa metoda o nazwie f. Jej zadaniem jest wyświetlenie nazwy klasy, w której została zdefiniowana, na ekranie. W klasie B, dziedziczącej z klasy A, również została zdefiniowana metoda o nazwie f, ale przyjmująca jeden argument typu int.

Page 27: Dziedziczenie

Przeciążenia metody a dziedziczenie

Jedynym zadaniem metody f z klasy B jest również wypisanie na ekran nazwy klasy, w której została zdefiniowana.Przeciążenie metod w przypadku dziedziczenia działa tak samo, jak gdyby odbyło się to w jednej klasie.

Page 28: Dziedziczenie

Program ilustrujący działanie przeciązenia

Wywołanie trzecie b.f() oraz czwarte b.f(0) są prawidłowe. W klasie B istnieje zarówno bezargumentowa metoda f odziedziczona z klasy A, jak i przeciążona metoda o nazwie f (zdefiniowana w klasie B), która przyjmuje argument typu int.

Page 29: Dziedziczenie

Przesyłanie pól i metod

• Przesyłanie metodWiemy już, że w klasach potomnych można przeciążyć metody zdefiniowane w klasie bazowej, jest to wręcz zgodne z logiką i intuicją, dziwiłby fakt, gdyby takiej możliwości nie było. Rozważmy przypadek, kiedy w klasie potomnej ponownie zdefiniujemy metodę o takiej samej nazwie i takich samych argumentach jak w klasie bazowej.

Page 30: Dziedziczenie

Przesyłanie metod

W klasie A znajduje się bezargumentowa metoda o nazwie f, która wyświetla na ekranie nazwę klasy, w której została zdefiniowana. Klasa B dziedziczy z klasy A, zgodnie z zasadami dziedziczenia, przyjmuje więc metodę f z klasy A.

Page 31: Dziedziczenie

Przesyłanie metod

Tymczasem w klasie B została ponownie zadeklarowana bezargumentowa metoda f (również wyświetlająca nazwę klasy, w której została zdefiniowana, czyli tym razem klasy B). Wydawać by się mogło, że w takim wypadku wystąpi konflikt nazw (dwukrotne zadeklarowanie metody f).Otóż zasada jest następująca: jeśli w klasie bazowej i klasie pochodnej występuje metoda o tej samej nazwie i argumentach, metoda z klasy bazowej jest przesłaniana.

Page 32: Dziedziczenie

Przesyłanie metod

Czyli w obiektach klasy bazowej będzie obowiązywała metoda z klasy bazowej, a w obiektach klasy pochodnej metoda z klasy pochodnej.Prześledźmy co pojawi się na ekranie po uruchomieniu klasy Main, która korzysta z obiektów klasy A i B.

Page 33: Dziedziczenie

Przesyłanie metod

Na ekranie pojawi się oczywiście najpierw znak A, a następnie znak B. Skoro bowiem obiekt a jest klasy A, to wywołanie a.f() powoduje wywołanie metody f z klasy A, czyli wyświetlenie znaku A. Z kolei obiekt b jest klasy B, zatem wywołanie b.f() powoduje uruchomienie metody f z klasy B i wyświetlenie znaku B.

Page 34: Dziedziczenie

Przesyłanie metod

Pojawić może się w tym miejscu pytanie, czy jest w takim razie możliwe wywołanie w klasie pochodnej metody przesłoniętej z klasy bazowej.Odwołanie takie jest możliwe, podobnie jak przy wywołaniu konstruktora klasy bazowej, korzystamy z instrukcji super w postaci:

super.nazwa_metody(argumenty);

Page 35: Dziedziczenie

Przykład

Page 36: Dziedziczenie

Przesyłanie pól

Pola klasy bazowej są przesyłane w sposób analogiczny jak w przypadku metod. Czyli, jeśli w klasie pochodnej zdefiniujemy pole o takiej samej nazwie jak w klasie bazowej, bezpośrednio dostępne będzie tylko pole klasy pochodnej.

Page 37: Dziedziczenie

Przesyłanie pól

Należy sobie uświadomić, że każdy obiekt klasy B zawiera teraz DWA pola o nazwie liczba. Jedno z nich pochodzi z klasy A, drugie z klasy B. Tym polom można z kolei przypisywać różne wartości.

Page 38: Dziedziczenie

Przesyłanie pola

Oczywiście, jeśli mamy obiekt takiej klasy B, to z dowolnej klasy zewnętrznej jesteśmy w stanie dostać się jedynie do pola liczba zdefiniowanego w klasie B. Jednak już z wnętrza klasy B za pomocą składni super możemy odwołać się do drugiego pola liczba.

Page 39: Dziedziczenie

Literatura

• „Praktyczny kurs Java”- Marcin Lis• „Java po C++”- Jan Bielecki