Lab07.pdf

(87 KB) Pobierz
Programowanie obiektowe /Java/
Laboratorium nr 7
1
Kompozycja
Polimorfizm (ang. polymorphism)
1
– „Termin używany w dwóch nieco różnych znaczeniach (które są czę-
sto mylone): (1) w terminologii obiektowej: możliwość istnienia wielu metod o tej samej nazwie, powiązana
z możliwością wyboru konkretnej metody podczas czasu wykonania (dynamicznym wiązaniem); (2) w termi-
nologii teorii typów i języków polimorficznych (np. w ML): umożliwienie definiowania funkcji lub procedur,
których argumenty i wynik mogą posiadać jednocześnie wiele typów;”
2
Przeciążanie
Przeciążanie (ang. overloading)
1
– „Sytuacja, w której ta sama nazwa (lub symbol) jest użyta do oznacze-
nia dwóch lub więcej funkcji (procedur, operatorów lub metod), zaś rozstrzygnięcie tej homonimii następuje
na podstawie kontekstu jej użycia (np. typu lub liczby argumentów operacji).”
3
Przesłonięcie
Przesłanianie (ang. overriding)
1
– „Odnosi się do sytuacji, kiedy implementacje funkcji (procedur, operato-
rów, metod) posiadających tę samą nazwę występują na różnych poziomach hierarchii dziedziczenia (co naj-
mniej dwóch). W tej sytuacji do obiektu stosuje się funkcję znajdującą się najniżej w części hierarchii od
korzenia do klasy tego obiektu; pozostałe funkcje o tej samej nazwie (z klas bardziej ogólnych, nadklas)
są ’przesłonięte’ przez tę funkcję. Przesłanianie jest realizacją strategii określanej jako ’pojedyncza dyspozy-
cja’ (ang. single dispatching) i jest ściśle powiązane z polimorfizmem. Przesłanianie wymaga dynamicznego
wiązania i jest jednym z ważnych elementów wspomagających ponowne użycie (ang. reuse).”
4
Adnotacja @Override
„Zapis @Override
2
chroni nas przed przypadkowym przeciążeniem tam, gdzie chodzi nam o przesłonięcie.”
Co stanie się jeżeli z linii 17 z adnotacją @Override zostanie usunięty komentarz?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package
pl.kielce.tu.lab7;
class
Calculator {
// przeciążenie printSum(int i, int j, int k, int l, int m, boolean b)
void
printSum() {
System.out.println("Calculator.printSum()");
}
// przeciążenie printSum()
void
printSum(int i,
int
j,
int
k,
int
l,
int
m,
boolean
b) {
System.out.println("Calculator.printSum(int
i, int j, int k, int l, int m, boolean b)");
}
}
class
Calculator2
extends
Calculator {
// przeciążenie czy przesłonięcie ???
// @Override
void
printSum(int i,
int
j,
int
k,
int
l,
boolean
b) {
System.out.println("Calculator2.printSum()");
}
1
Słownik
2
Thinking
terminów z zakresu obiektowości. K. Subieta, Akademicka Oficyna Wydawnicza PLJ, Warszawa 1999
in Java, Bruce Eckel, Wydanie IV, Helion, 2006
1
22
23
24
25
26
27
// przesłonięcie printSum(int i, int j, int k, int l, int m, boolean b)
@Override
void
printSum(int i,
int
j,
int
k,
int
l,
int
m,
boolean
b) {
System.out.println("printSum(int
i, int j, int k, int l, int m, boolean b)");
}
}
Przykład 1: src/pl/kielce/tu/lab7/TestAnnotation.java
{link}
5
Rzutowanie
Kast (ang. cast)
1
– „Termin C, C++ i innych interfejsów oznaczający operator konwersji typu. Zwykle
przyjmuje postać nazwy typu w nawiasach okrągłych, stawianej przed wielkością podlegającą konwersji typu.”
Kast w dół (ang. downcast) - „Konwersja typu na typ stojący niżej w hierarchii (na podtyp).” Kast w górę
(ang. upcast) - „Konwersja typu na typ stojący wyżej w hierarchii (na nadtyp).”
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package
pl.kielce.tu.lab7;
class
Pojazd {
}
class
Samochod
extends
Pojazd {
}
class
Motocykl
extends
Pojazd {
}
public class
TestCast {
public static void
main(String[] args) {
Pojazd[] p =
new
Pojazd[2];
p[0] =
new
Samochod();
p[1] =
new
Motocykl();
Samochod s = (Samochod) p[0];
Motocykl m = (Motocykl) p[1];
// java.lang.ClassCastException
m = (Motocykl) p[0];
// java.lang.ClassCastException
s = (Samochod) p[1];
}
}
Przykład 2: src/pl/kielce/tu/lab7/TestCast.java
{link}
6
Wiązanie
Statyczne wiązanie (ang. static binding)
1
– „Wiązanie nazw występujących w programie, które ma miej-
sce podczas kompilacji.” Wiązanie dynamiczne (ang. dynamic binding)
1
– „Wiązanie nazw występujących
w programie na etapie wykonania programu; inaczej późne wiązanie.”
7
Kowariancja typów zwracanych
Przesłonięta metoda klasy pochodnej
2
może zwracać typ pochodny względem typu zwracanego przez
metodę bazową. W przykładzie poniżej proszę porównać typ zwracany metody
potomek().
1
2
3
package
pl.kielce.tu.lab7;
class
Zwierze{
2
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
void
odglos(){
System.out.println("???");
}
void
dzwiek(int iloscPowtorzen){
for(int
i = 0; i < iloscPowtorzen; i++)
odglos();
}
Zwierze potomek(){
return new
Zwierze();
}
}
class
Kot
extends
Zwierze{
@Override
void
odglos(){
System.out.println("Miau");
}
@Override
Kot potomek(){
return new
Kot();
}
}
class
Pies
extends
Zwierze{
@Override
void
odglos(){
System.out.println("Hau");
}
@Override
Pies potomek(){
return new
Pies();
}
}
public class
TestCovariance {
public static void
main (String [] args){
Zwierze [] z =
new
Zwierze[2];
z[0] =
new
Kot();
z[1] =
new
Pies();
Kot k = (Kot) z[0];
Pies p = (Pies) z[1];
//java.lang.ClassCastException: Pies cannot be cast to Kot
k = (Kot) z[1];
//java.lang.ClassCastException: Kot cannot be cast to Pies
p = (Pies) z[0];
}
}
Przykład 3: src/pl/kielce/tu/lab7/TestCovariance.java
{link}
8
Klasa abstrakcyjna
Klasa abstrakcyjna (ang. abstract class)
1
– „Klasa zawierająca własności (np. metody) dziedziczone przez
jej podklasy, ale nie posiadająca bezpośrednich wystąpień obiektów.”
Metoda abstrakcyjna (ang. abstract method)
1
– „Metoda, której specyfikacja znajduje się w danej klasie,
ale której implementacje (być może różne) znajdują się w podklasach.”
1
2
3
4
5
6
package
pl.kielce.tu.lab7;
abstract class
Figura {
abstract public void
rysuj();
public static void
rysujFigury(Figura[] figury) {
3
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
for
(Figura f : figury)
f.rysuj();
System.out.println();
}
}
class
Kwadrat
extends
Figura {
@Override
public void
rysuj() {
System.out.print("Kwadrat
");
}
}
class
Kolo
extends
Figura {
@Override
public void
rysuj() {
System.out.print("Koło
");
}
}
public class
TestAbstract {
public static void
main(String[] args) {
Figura.rysujFigury(new Figura[] {
new
Kolo(),
new
Kolo() });
Figura.rysujFigury(new Figura[] {
new
Kwadrat(),
new
Kwadrat() });
Figura.rysujFigury(new Figura[] {
new
Kwadrat(),
new
Kolo() });
Figura.rysujFigury(new Figura[] {
new
Figura() {
@Override
public void
rysuj() {
System.out.print("Nienazwana
figura ");
}
} });
}
}
Przykład 4: src/pl/kielce/tu/lab7/TestAbstract.java
{link}
9
Interfejs
Interfejs (ang. interface)
1
– „Ogólnie, środki służące do komunikacji pomiędzy modułami systemu lub
komunikacji systemu z użytkownikiem. W innym znaczeniu (OMG, ODMG) interfejs jest synonimem specyfi-
kacji klasy. Interfejs do obiektu składa się z sygnatur wszystkich metod, które mogą być w stosunku do niego
użyte. Operacje na obiekcie mogą odbywać się poprzez wysłanie do niego komunikatu zgodnego z dowolną
z sygnatur należących do jego interfejsu.”
„słowo kluczowe
intef ace
2
generuje zupełnie abstrakcyjna klasę bazową, która jest całkowicie pozbawiona
implementacji. ”
1
2
3
4
5
6
7
8
9
10
11
12
13
14
package
pl.kielce.tu.lab7;
interface
I1 {
void
m1();
}
interface
I2 {
void
m2();
}
interface
I3
extends
I2 {
void
m3();
}
4
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
public class
TestInterface
implements
I1, I3 {
public void
m1() {
System.out.println("m1");
}
public void
m2() {
System.out.println("m2");
}
public void
m3() {
System.out.println("m3");
}
public static void
main(String[] args) {
TestInterface i =
new
TestInterface();
I1 i1 = i;
i1.m1();
I2 i2 = i;
i2.m2();
I3 i3 = i;
i3.m2();
i3.m3();
}
}
Przykład 5: src/pl/kielce/tu/lab7/TestInterface.java
{link}
Problem związany z implementacją wielu interfejsów posiadających metody o takich samych sygnaturach:
interface I1
Integer m();
}
interface I2
String m();
}
//ERROR: The
public class
}
{
{
return type is incompatible with I1.m(), I2.m()
Test implements I1, I2{
10
Wytwórnia (fabryka)
Fabryka (ang. factory)
1
– „Zestaw metod, operatorów lub instrukcji służący do tworzenia obiektów.”
„Zamiast wprost wywoływać konstruktor możemy wywoływać metodę obiektu – wytwórni
2
, który gene-
ruje implementacje interfejsu – w ten sposób (przynajmniej teoretycznie) można całkowicie odizolować własny
kod od implementacji interfejsu, co umożliwia transparentną wymianę jednej implementacji na inną.”
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package
pl.kielce.tu.lab7;
interface
Monitor {
void
wyswietlajObraz();
}
interface
FabrykaMonitorow {
Monitor pobierzMonitor();
}
class
MonitorCRT
implements
Monitor {
public void
wyswietlajObraz() {
System.out.println("MonitorCRT");
}
}
5
Zgłoś jeśli naruszono regulamin