• Nie Znaleziono Wyników

To budowanie nowych klas na bazie już istniejących. Każda taka nowa klasa przejmuje zachowanie i właściwości klasy bazowej.

N/A
N/A
Protected

Academic year: 2021

Share "To budowanie nowych klas na bazie już istniejących. Każda taka nowa klasa przejmuje zachowanie i właściwości klasy bazowej."

Copied!
19
0
0

Pełen tekst

(1)

Dziedziczenie

Monika Wrzosek (IM UG) Programowanie obiektowe 92 / 122

(2)

Dziedziczenie

To jeden z fundamentów programowania obiektowego.

To budowanie nowych klas na bazie już istniejących. Każda taka nowa klasa przejmuje zachowanie i właściwości klasy bazowej.

- Na poprzednich wykładach powstała klasa Punkt, która przechowywała informację o współrzędnych punktu na płaszczyźnie.

- Załóżmy, że zachodzi potrzeba określenia położenia punktu w trzech wymiarach.

Moglibyśmy utworzyć nową klasę, np. o nazwie Punkt3D:

p u b l i c c l a s s Punkt3D { i n t x , y , z ;

}

- Do tej klasy należałoby dopisać pełny zestaw metod, które znajdowały się w klasie Punkt, oraz dodatkowe metody operujące na współrzędnej z. W dużej części powtórzylibyśmy już raz napisany kod.

- Klasa Punkt3D jest rozszerzeniem klasy Punkt. 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. Jest to tak

zwane dziedziczenie.

(3)

Dziedziczenie

- Powiemy, że klasa Punkt3D dziedziczy po klasie Punkt, czyli przejmuje jej pola i metody oraz dodaje swoje własne.

- Klasę Punkt nazwiemy klasą bazową/nadrzędną/nadklasą (ang. superclass).

- Klasę Punkt3D nazwiemy klasą potomną/pochodną/podrzędną/podklasą (ang.

subclass).

Składnia

class klasa_potomna extends klasa_bazowa {

treść klasy }

Przykład:

p u b l i c c l a s s Punkt3D e x t e n d s Punkt { i n t z ;

}

Taki zapis oznacza, że klasa Punkt3D przejęła wszystkie właściwości klasy Punkt, a dodatkowo otrzymała pole typu int o nazwie z.

Monika Wrzosek (IM UG) Programowanie obiektowe 94 / 122

(4)

p u b l i c c l a s s Punkt { i n t x , y ;

i n t p o b i e r z X ( ) { r e t u r n x ; }

i n t p o b i e r z Y ( ) { r e t u r n y ; }

v o i d ustawX (i n t wspX ) { x = wspX ;

}

v o i d ustawY (i n t wspY ) { y = wspY ;

}

v o i d ustawXY (i n t wspX , i n t wspY ) { x = wspX ;

y = wspY ; }

v o i d w y s w i e t l ( ) {

S y s t e m . o u t . p r i n t l n (" x = " + x + " , y = " + y ) ; }

}

p u b l i c c l a s s Punkt3D e x t e n d s Punkt { i n t z ;

}

(5)

p u b l i c c l a s s Main {

p u b l i c s t a t i c v o i d main ( S t r i n g a r g s [ ] ) { Punkt3D P = new Punkt3D ( ) ;

P . ustawX ( 1 0 0 ) ; P . ustawY ( 2 0 0 ) ; P . w y s w i e t l ( ) ;

S y s t e m . o u t . p r i n t l n (" z = " + z ) ;

P . ustawXY ( 3 , 4 ) ; P . w y s w i e t l ( ) ;

S y s t e m . o u t . p r i n t l n (" z = " + z ) ;

x = 1 0 0 , y = 200 z = 0 ;

x = 3 , y = 4 z = 0 ;

Klasa Punkt3D nie jest jednak w pełni funkcjonalna, należałoby dopisać metody operujące na nowym polu z, np. ustawZ, pobierzZ, ustawXYZ.

Monika Wrzosek (IM UG) Programowanie obiektowe 96 / 122

(6)

p u b l i c c l a s s Punkt3D e x t e n d s Punkt { i n t z ;

i n t p o b i e r z Z ( ) { r e t u r n z ; }

v o i d ustawZ (i n t wspZ ) { z = wspZ ;

}

v o i d ustawXYZ (i n t wspX , i n t wspY , i n t wspZ ) { x = wspX ;

y = wspY ; z = wspZ ; }

v o i d ustawXYZ ( Punkt3D A) {

x = A . x ; y = A . y ; z = A . z ; }

v o i d ustawXYZ ( Punkt P , i n t wspZ ) { x = P . x ;

y = P . y ; z = wspZ ; }

}

(7)

Konstruktor klasy potomnej

p u b l i c c l a s s Punkt3D e x t e n d s Punkt { i n t z ;

Punkt3D ( ) { x = 1 ; y = 1 ; z = 1 ; }

Punkt3D (i n t wspX , i n t wspY , i n t wspZ ) { x = wspX ;

y = wspY ; z = wspZ ; }

Punkt3D ( Punkt3D A) { x = A . x ;

y = A . y ; z = A . z ; }

/∗ p o z o s t a ł e metody k l a s y Punkt3D ∗/

}

- Kod tych konstruktorów w znacznej części dubluje się z kodem konstruktorów klasy Punkt.

- Czy można wykorzystać konstruktor klasy Punkt w klasie Punkt3D; ogólniej - konstruktor klasy bazowej w konstruktorze klasy potomnej?

Tak, służy do tego metoda super().

Monika Wrzosek (IM UG) Programowanie obiektowe 98 / 122

(8)

- Metoda super() to wywołanie konstruktora klasy bazowej.

- Ważne jest, aby była ona pierwszą instrukcją konstruktora klasy potomnej. Próba umieszczenia tej instrukcji w innym miejscu spowoduje błąd kompilacji.

p u b l i c c l a s s Punkt3D e x t e n d s Punkt { i n t z ;

Punkt3D ( ) { s u p e r( ) ; z = 1 ; }

Punkt3D (i n t wspX , i n t wspY , i n t wspZ ) { s u p e r( wspX , wspY ) ;

z = wspZ ; }

Punkt3D ( Punkt3D A) { s u p e r(A ) ;

z = A . z ; }

}

- W pierwszym konstruktorze wywołujemy bezargumentową metodę super, która powoduje wywołanie bezargumentowego konstruktora klasy bazowej. Taki konstruktor (bezargumentowy) istnieje w klasie Punkt, więc konstrukcja jest OK.

- W drugim konstruktorze wywołujemy metodę super, przekazując jej dwa parametry

typu int. Ponieważ w klasie Punkt istnieje konstruktor dwuargumentowy przyjmujący

dwie wartości typu int, ta konstrukcja też jest OK.

(9)

p u b l i c c l a s s Punkt3D e x t e n d s Punkt { i n t z ;

Punkt3D ( ) { s u p e r( ) ; z = 1 ; }

Punkt3D (i n t wspX , i n t wspY , i n t wspZ ) { s u p e r( wspX , wspY ) ;

z = wspZ ; }

Punkt3D ( Punkt3D A) { s u p e r(A ) ;

z = A . z ; }

}

- Trzeci konstruktor przyjmuje jeden argument typu (klasy) Punkt3D, ale w klasie Punkt nie ma konstruktora, który przyjmowałby argument tego typu! Jest konstruktor:

Punkt ( Punkt P ) { x = P . x ; y = P . y ; }

ale przyjmuje on argument typu Punkt, a nie Punkt3D. Czy wystąpi więc błąd kompilacji?

- Nie. Jeśli oczekiwany jest argument klasy X, a podany zostanie argument klasy Y, która jest klasą potomną dla X, błędu nie będzie (nastąpi tzw. rzutowanie obiektu).

Monika Wrzosek (IM UG) Programowanie obiektowe 100 / 122

(10)

Przeciążanie metod a dziedziczenie

p u b l i c c l a s s A { p u b l i c v o i d f ( ) {

S y s t e m . o u t . p r i n t l n (" Metoda f ( ) z k l a s y A") ; }}

p u b l i c c l a s s B e x t e n d s A { p u b l i c v o i d f (i n t l i c z b a ) {

S y s t e m . o u t . p r i n t l n (" Metoda f ( i n t ) z k l a s y B") ; }

}

p u b l i c c l a s s Main {

p u b l i c s t a t i c v o i d main ( S t r i n g a r g s [ ] ) { A a = new A ( ) ;

B b = new B ( ) ;

// p r a w i d ł owe wywo ł a n i e , w k l a s i e A i s t n i e j e metoda f ( ) : a . f ( ) ; // Wynik : Metoda f ( ) z k l a s y A

// n i e p r a w i d ł owe wywo ł a n i e , w k l a s i e A n i e ma metody f ( i n t ) : // a . f ( 0 ) ;

// oba p r a w i d ł owe , w k l a s i e B i s t n i e j ą metody f ( ) i f ( i n t ) : b . f ( ) ; // Wynik : Metoda f ( ) z k l a s y A

b . f ( 0 ) ; // Wynik : Metoda f ( i n t ) z k l a s y B }

}

(11)

Przesłanianie metod

- Wiemy, że w klasach potomnych można przeciążać metody klasy bazowej.

- Co się jednak stanie, kiedy w klasie potomnej ponownie zdefiniujemy metodę o takiej samej nazwie i takich samych argumentach jak w klasie bazowej?

p u b l i c c l a s s A { p u b l i c v o i d f ( ) {

S y s t e m . o u t . p r i n t l n (" Metoda f z k l a s y A") ; }}

p u b l i c c l a s s B e x t e n d s A { p u b l i c v o i d f ( ) {

S y s t e m . o u t . p r i n t l n (" Metoda f z k l a s y B") ; }}

- Klasa potomna B przejmuje z klasy A funkcję f (), ale sama również ją definiuje.

- Wydawać by się mogło, że w takim wypadku wystąpi konflikt nazw (dwukrotne zadeklarowanie metody f ()), kompilator nie zgłasza błędów.

Przesłanianie/przykrywanie/nadpisywanie (ang. overriding )

Jeśli w klasie bazowej i pochodnej są metody o tej samej nazwie i argumentach, metoda z klasy bazowej jest przesłaniana.

W obiektach klasy bazowej będzie zatem obowiązywała metoda z klasy bazowej, a w obiektach klasy pochodnej - metoda z klasy pochodnej.

Monika Wrzosek (IM UG) Programowanie obiektowe 102 / 122

(12)

Przesłanianie metod

p u b l i c c l a s s A { p u b l i c v o i d f ( ) {

S y s t e m . o u t . p r i n t l n (" Metoda f z k l a s y A") ; }

}

p u b l i c c l a s s B e x t e n d s A { p u b l i c v o i d f ( ) {

S y s t e m . o u t . p r i n t l n (" Metoda f z k l a s y B") ; }

}

p u b l i c c l a s s Main {

p u b l i c s t a t i c v o i d main ( S t r i n g a r g s [ ] ) { A a = new A ( ) ;

B b = new B ( ) ; a . f ( ) ;

b . f ( ) ; }

}

Metoda f z k l a s y A Metoda f z k l a s y B

(13)

Czy możliwe jest wywołanie w klasie pochodnej przesłoniętej metody z klasy bazowej?

p u b l i c c l a s s A { p u b l i c v o i d f ( ) {

S y s t e m . o u t . p r i n t l n (" Metoda f z k l a s y A") ; }

}

p u b l i c c l a s s B e x t e n d s A { p u b l i c v o i d f ( ) {

S y s t e m . o u t . p r i n t l n (" Metoda f z k l a s y B") ; }

}

Czy w obiekcie klasy B można wywołać metodę f pochodzącą z klasy A?

Odwołanie do przesłoniętej metody klasy bazowej uzyskujemy dzięki wywołaniu:

super.nazwa_metody(argumenty);

Monika Wrzosek (IM UG) Programowanie obiektowe 104 / 122

(14)

p u b l i c c l a s s A { p u b l i c v o i d f ( ) {

S y s t e m . o u t . p r i n t l n (" K l a s a A") ; }

}

p u b l i c c l a s s B e x t e n d s A {

// t a metoda p r z e s ł a n i a metod ę f z k l a s y A ,

// a l e wywo ł u j e r ó w n i e ż p r z e s ł o n i ę t ą metod ę f z k l a s y A : p u b l i c v o i d f ( ) {

s u p e r. f ( ) ;

S y s t e m . o u t . p r i n t l n (" K l a s a B") ; }

// t a metoda wywo ł u j e metod ę f z k l a s y B : p u b l i c v o i d g ( ) {

f ( ) ; }

// t a metoda wywo ł u j e metod ę f z k l a s y A : p u b l i c v o i d h ( ) {

s u p e r. f ( ) ; }

}

(15)

p u b l i c c l a s s Main {

p u b l i c s t a t i c v o i d main ( S t r i n g a r g s [ ] ) { A a = new A ( ) ;

B b = new B ( ) ;

S y s t e m . o u t . p r i n t l n (" Wynik wywo ł a n i a a . f ( ) : ") ; a . f ( ) ;

S y s t e m . o u t . p r i n t l n (" \ nWynik wywo ł a n i a b . f ( ) : ") ; b . f ( ) ;

S y s t e m . o u t . p r i n t l n (" \ nWynik wywo ł a n i a b . g ( ) : ") ; b . g ( ) ;

S y s t e m . o u t . p r i n t l n (" \ nWynik wywo ł a n i a b . h ( ) : ") ; b . h ( ) ;

} }

Wynik wywo ł a n i a a . f ( ) : K l a s a A

Wynik wywo ł a n i a b . f ( ) : K l a s a A

K l a s a B

Wynik wywo ł a n i a b . g ( ) : K l a s a A

K l a s a B

Wynik wywo ł a n i a b . h ( ) : K l a s a A

Monika Wrzosek (IM UG) Programowanie obiektowe 106 / 122

(16)

- W klasie potomnej B:

1. zdefiniowano metodę f , która przesłania metodę f z klasy A. Jednak w tej metodzie jest wywoływana (za pomocą składni super ) metoda przesłonięta.

Dopiero po tym wywołaniu zostaje wyświetlona nazwa klasy B.

2. Metoda g wywołuje w standardowy sposób metodę f (czyli będzie to metoda f z klasy B).

3. Metoda h korzysta ze składni super: super.f(), zatem wywołuje metodę f zdefiniowaną w klasie A.

- W klasie Main:

1. wywoływana jest metoda f obiektu klasy A, zatem na ekranie pojawia się napis Klasa A;

2. wywoływana jest metoda f obiektu b. Ponieważ najpierw wywołuje ona metodę f klasy A, a potem wyświetla nazwę klasy B, jej wynikiem są dwa teksty:

Klasa A i Klasa B;

3. wywoływana jest metoda g obiektu b, której jedynym zadaniem jest wywołanie metody f z klasy B. Wynik jest więc identyczny jak w punkcie 2;

4. wywoływana jest metoda h obiektu b. Jest w niej uruchamiana (za pomocą

super ) metoda f z klasy A, więc wyświetla się tekst Klasa A.

(17)

Przesłanianie pól

Pola klas bazowych są przesłaniane tak samo jak w przypadku metod.

p u b l i c c l a s s A { p u b l i c i n t l i c z b a ; }

p u b l i c c l a s s B e x t e n d s A { p u b l i c i n t l i c z b a ;

- W klasie A zostało zdefiniowane pole o nazwie liczba i typie int.

- W klasie B, która dziedziczy po A, ponownie zostało zadeklarowane pole o takiej samej nazwie i identycznym typie.

- Każdy obiekt klasy B będzie więc zawierał DWA pola o nazwie liczba: jedno pochodzące z klasy A, drugie z B.

- Jeśli mamy obiekt klasy B, to z dowolnej klasy zewnętrznej możemy 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ę również do drugiego pola liczba (pochodzącego z klasy A).

Monika Wrzosek (IM UG) Programowanie obiektowe 108 / 122

(18)

p u b l i c c l a s s A { p u b l i c i n t l i c z b a ; }

p u b l i c c l a s s B e x t e n d s A { p u b l i c i n t l i c z b a ;

p u b l i c v o i d u s t a w L i c z b a A (i n t l i c z b a ) { s u p e r. l i c z b a = l i c z b a ;

}

p u b l i c v o i d u s t a w L i c z b a B (i n t l i c z b a ) { t h i s. l i c z b a = l i c z b a ;

}

p u b l i c i n t p o b i e r z L i c z b a A ( ) { r e t u r n s u p e r. l i c z b a ;

}

p u b l i c i n t p o b i e r z L i c z b a B ( ) { r e t u r n l i c z b a ;

} }

(19)

p u b l i c c l a s s Main {

p u b l i c s t a t i c v o i d main ( S t r i n g a r g s [ ] ) { B b = new B ( ) ;

b . u s t a w L i c z b a A ( 0 ) ; b . u s t a w L i c z b a B ( 1 ) ;

S y s t e m . o u t . p r i n t (" Warto ś ć p r z e s ł o n i ę t e g o p o l a l i c z b a : ") ; S y s t e m . o u t . p r i n t l n ( b . p o b i e r z L i c z b a A ( ) ) ;

S y s t e m . o u t . p r i n t (" Warto ś ć p o l a l i c z b a z k l a s y B : ") ; S y s t e m . o u t . p r i n t l n ( b . p o b i e r z L i c z b a B ( ) ) ;

} }

Warto ś ć p r z e s ł o n i ę t e g o p o l a l i c z b a : 0 Warto ś ć p o l a l i c z b a z k l a s y B : 1

Monika Wrzosek (IM UG) Programowanie obiektowe 110 / 122

Cytaty

Powiązane dokumenty

W pierwszej turze eksperymentu (czyli w drugim dniu pobytu) po pierw- szej i drugiej zabawie na pytanie „powiedz, która zabawa bardziej ci się podobała – pierwsza

miejscowości wyruszają równocześnie naprzeciw siebie samochód osobowy jadący z prędkością 70 km/h i samochód ciężarowy. jadący z prędkością

"Brakowało nam kontaktu z panią i kolegami" - zdradzili nam drugoklasiści. Niektórzy doświadczyli odosobnienia ucząc się na odległość. Po prostu tęsknili za szkołą.

W podobny sposób jak uzyskaliśmy pochodne drugiego i trzeciego rzędu poprzez dwu- i trzykrotne różniczkowanie funkcji, możemy zdefiniować 1 pochodną dowolnego rzędu 2 naturalnego

 porównuje cykle rozwojowe paprotników oraz nagozalążkowych i na tej podstawie określa, jakie cechy pojawiły się u roślin nagozalążkowych oraz wyjaśnia ich znaczenie.

prostą m, punkt A, trójkąt ABC. Pamiętaj, że punkt A’ będzie po drugiej stronie prostej m, w takiej samej odległości od prostej m jak punkt A, odcinek AA’ będzie prostopadły

„Should” służy do udzielania rad, mówienia co ktoś powinien lub nie powinien zrobić... You look tired, you should go

W definicji metody, this jest parametrem domy lnym, który zawiera referencj do obiektu, który otrzymuje odwo anie danej metody.. Na przyk ad, je eli pragnie si wywo a funkcj ,