,
[ 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 ] |
Odnośniki
|