, Java_Programowanie_obiektowe_japrob 

[ Pobierz całość w formacie PDF ]

tected i był dostępny wyłącznie w Javie 1.0. Umożliwiał on ustawienie widzialności
elementu wyłącznie w podklasach, bez względu na to, czy należały one do tego sa-
mego pakietu czy do innych. Nieznacznie różniło się to od standardu protected, który
poza widzialnością w podklasach zapewnia widzialność w innych klasach tego samego
pakietu.
Analizując modyfikator private w odniesieniu do klas lokalnych, należy zwrócić uwagę,
że nie działa on w pełni tak, jakbyśmy oczekiwali. Listing 2.97 ukazuje klasę lokalną
zadeklarowaną z metodą prywatną.
Rozdział 2. f& Klasy i obiekty w Javie 107
Listing 2.97. Klasa lokalna z metodą prywatną
public int i;
private class Lokalna {
private int wynik() { return i; }
}
Takie rozwiązanie powoduje, że metoda wynik  prywatna dla tej klasy  jest jed-
nak widoczna poza nią. Kompilator nie zgłosi błędu przy kompilacji fragmentu pro-
gramu z listingu 2.98.
Listing 2.98. Niekonsekwencja prywatności w klasie z listingu 2.97
void doSth() {
i = 100;
Lokalna l = new Lokalna();
System.err.println("wynik: " + l.wynik());
}
Metody i pola prywatne z założenia nie powinny być widoczne poza klasą, tak więc
osobiście oczekiwałem, że metoda wynik nie będzie widzialna dla kompilatora. We
wczesnych subwersjach Javy 1.1 pola i metody prywatne klas lokalnych były trakto-
wane inaczej, to znaczy pola prywatne były niewidoczne, a metody prywatne widoczne.
Błąd ten naprawiono i w wyższych wersjach zarówno pola, jak i metody prywatne są
widoczne poza klasą. Moim zdaniem jest to niezgodne z konwencją modyfikatora
private. Korzystając z niego w klasach lokalnych, należy więc pamiętać o tej nieści-
słości. Na modyfikator private zwracałem też uwagę w paragrafach 2.1.4.  Hermety-
zacja i modyfikator private oraz 2.1.11.  Kolejność inicjacji klas .
2.9.2. Pokrywanie modyfikatorów dostępu
Raz nadany zakres dostępu może zostać w przyszłości rozszerzony. Oznacza to, że je-
śli zadeklarowaliśmy metodę bez modyfikatora, metoda pokrywająca może również
tak być zadeklarowana oraz z modyfikatorami protected lub public. Jeśli deklarujemy
metodę jako protected, pokrywając ją, możemy (poza tym samym modyfikatorem)
użyć modyfikatora public. Oczywiście możemy również przedeklarować zakres
private na dowolny inny. Jakkolwiek konwencja jest zachowana w stosunku do wy-
mienionych wcześniej układów, wynika to z faktu, że element prywatny jest niewi-
doczny poza swoją klasą. Odwrotna sytuacja nie jest możliwa, to znaczy zakres wi-
dzialności nie może zostać zawężony. Tak więc, jeśli deklarujemy klasę:
public class A {
int mi() {
return 0;
}
}
wtedy poniższa deklaracja jest poprawna:
public class B extends A {
public int mi() { return 0; }
}
108 Java. Programowanie obiektowe
natomiast następna już nie:
public class B extends A {
private int mi() { return 0; } // błąd kompilacji
}
Wyjątek dotyczy jedynie zakresu widzialności klas. Oznacza to, że jeśli mamy w pew-
nym pakiecie deklarację klasy:
package ppp;
public class P { }
wtedy możemy zawęzić widzialność klasy potomnej w następujący sposób:
package ppp;
class Q extends P { }
// zakres widzialności tylko w obrębie pakietu
Przy tak zadeklarowanych klasach próba użycia:
import ppp.*;
class Z {
P p = new P();
Q i = new Q(); // klasa niewidoczna
}
w przypadku klasy Q zakończy się niepowodzeniem.
Wróćmy jednak do widzialności metod. Zadeklarujmy klasy A i B w sposób podany na
listingu 2.99.
Listing 2.99. Przykładowa deklaracja dwóch klas
package ppp;
public class A {
int mi() { return 0; }
}
package ppp;
public class B extends A {
public int mi() { return 0; }
}
Jak się należało spodziewać, próba użycia metody mi obiektu a pokazana na listingu
2.100 nie powiedzie się, gdyż metoda ta będzie niedostępna.
Listing 2.100. Błędna próba użycia klas z listingu 2.99
import ppp.*;
class C {
A a = new A();
B b = new B();
void init() {
int i;
i = a.mi(); // metoda niedostępna
Rozdział 2. f& Klasy i obiekty w Javie 109
i = b.mi();
}
}
Jednak bardzo dziwne jest to, że również w przypadku próby pokazanej na listingu
2.101 dostęp do tej metody będzie niemożliwy.
Listing 2.101. Inna próba użycia klas z listingu 2.99
import ppp.*;
class C {
A a = new B(); // inny sposób tworzenia
B b = new B();
void init() {
int i;
i = a.mi(); // metoda niedostępna
i = b.mi();
}
}
Mam wrażenie, że w tym przypadku, jakkolwiek referencja do metody mi dotyczy [ Pobierz całość w formacie PDF ]
  • zanotowane.pl
  • doc.pisz.pl
  • pdf.pisz.pl
  • osy.pev.pl