Например, библиотека классов Java SE 7 API хранится в пакетах java, javax, org. Пакет java содержит только подпакеты applet, awt, beans, dyn, io, lang, math, net, nio, rmi, security, sql, text, util и ни одного класса. Эти пакеты имеют свои подпакеты, например пакет создания ГИП (Графический интерфейс пользователя) и графики java.awt содержит классы, интерфейсы и подпакеты color, datatransfer, dnd, event, font, geom, im, image, print.
Конечно, количество и состав пакетов Java SE API меняется с каждой новой версией.
Права доступа к членам класса
Пришло время подробно рассмотреть различные ограничения доступа к полям и методам класса.
Рассмотрим большой пример. Пусть имеется пять классов, размещенных в двух пакетах, как показано на рис. 3.1.
package p1; | package p2; | ||
Inp1 | Inp2 | ||
Base | |||
\- | —Derived p2 | ||
Derivedpl | |||
Рис. 3.1. Размещение наших классов по пакетам |
В файле Basejava описаны три класса: Inp1, Base и класс Derivedp1, расширяющий класс Base. Эти классы размещены в пакете p1. В классе Base определены переменные всех четырех типов доступа, а в методах f () классов Inp1 и Derivedp1 сделана попытка доступа ко всем полям класса Base. Неудачные попытки отмечены комментариями. В комментариях помещены сообщения компилятора. Листинг 3.1 показывает содержимое этого файла.
package p1; class Inp1{
public void f(){
Base b = new Base();
// b.priv = 1; // "priv has private access in p1.Base" b.pack = 1; b.prot = 1;
b.publ = 1;
}
}
public class Base{
private int priv = 0;
int pack = 0; protected int prot = 0; public int publ = 0;
}
class Derivedp1 extends Base{ public void f(Base a){
// a.priv = 1; // "priv has private access in p1.Base"
a.pack = 1; a.prot = 1; a.publ = 1;
// priv = 1; // "priv has private access in p1.Base"
pack = 1; prot = 1; publ = 1;
}
}
Как видно из листинга 3.1, в пакете недоступны только закрытые, private, поля другого класса.
В файле Inp2java описаны два класса: Inp2 и класс Derivedp2, расширяющий класс Base. Эти классы находятся в другом пакете p2. В них тоже сделана попытка обращения к полям класса Base. Неудачные попытки прокомментированы сообщениями компилятора. Листинг 3.2 показывает содержимое этого файла.
Напомним, что класс Base должен быть помечен при своем описании в пакете p1 модификатором public, иначе из пакета p2 не будет видно ни одного его члена.
Листинг 3.2. Файл Inp2.java с описанием пакета р2
package p2; import p1.Base; class Inp2{
public static void main(String[] args){
Base b = new Base();
// b.priv = 1; // "priv has private access in p1.Base"
// b.pack = 1; // "pack is not public in p1.Base;
// cannot be accessed from outside package" // b.prot = 1; // "prot has protected access in p1.Base"
b.publ = 1;
}
}
class Derivedp2 extends Base{ public void f(Base a){
// "priv has private access in p1.Base"
// priv = 1;
// pack = 1;
prot = 1; publ = 1; super.prot = 1;
}
}
// "pack is not public in p1.Base; cannot // be accessed from outside package"
// "prot has protected access in p1.Base"
// "priv has private access in p1.Base"
// "pack is not public in p1.Base; cannot // be accessed from outside package"
Здесь, в другом пакете, доступ ограничен в большей степени.
Из независимого класса можно обратиться только к открытым, public, полям класса другого пакета. Из подкласса можно обратиться еще и к защищенным, protected, полям, но только унаследованным непосредственно, а не через экземпляр суперкласса.
Все указанное относится не только к полям, но и к методам.
Подытожим в табл. 3.1 все сказанное.
Класс | Пакет | Пакет и подклассы | Все классы | |
private | + | |||
"package" | + | + | ||
protected | + | + | * | |
public | + | + | + | + |
* Особенность доступа к protected-полям и методам из чужого пакета отмечена звездочкой. |
Размещение пакетов по файлам
То обстоятельство, что class-файлы, содержащие байт-коды классов, должны быть размещены по соответствующим каталогам, накладывает свои особенности на процесс компиляции и выполнения программы.
Обратимся к уже рассмотренному примеру. Пусть в каталоге D:\jdk1.3\MyProgs\ch3 есть пустой подкаталог classes и два файла — Basejava и Inp2java, — содержимое которых показано в листингах 3.1 и 3.2. Рисунок 3.2 демонстрирует структуру каталогов уже после компиляции.
Мы можем проделать всю работу вручную.
1. В каталоге classes создаем подкаталоги р1 и p2.
2. Переносим файл Basejava в каталог р1 и делаем р1 текущим каталогом.
ch3
-classes-i- р1 —г- Base.class
Base.java
-Derivedpi .class
4np2.java
4np1 .class
T
Derivedp2.class
LP2
I—Inp2.class
Рис. 3.2. Структура каталогов
3. Компилируем Base.java, получая в каталоге р1 три файла: Base.class, Inp1.class, Derivedp1.class.