Выбрать главу

// "pack is not public in p1.Base; cannot // be accessed from outside package"

Здесь, в другом пакете, доступ ограничен в большей степени.

Из независимого класса можно обратиться только к открытым, public, полям класса другого пакета. Из подкласса можно обратиться еще и к защищенным, protected, полям, но только унаследованным непосредственно, а не через экземпляр суперкласса.

Все указанное относится не только к полям, но и к методам.

Подытожим в табл. 3.1 все сказанное.

Таблица 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.

4. Переносим файл Inp2java в каталог p2.

5. Снова делаем текущим каталог classes.

6. Компилируем второй файл, указывая путь p2\Inp2.java.

7. Запускаем программу java p2.Inp2.

Вместо шагов 2 и 3 можно просто создать три class-файла в любом месте, а потом перенести их в каталог p1. В class-файлах не хранится никакая информация о путях к файлам.

Смысл действий 5 и 6 в том, что при компиляции файла Inp2java компилятор уже должен знать класс p1.Base, а отыскивает он файл с этим классом по пути p1\Base.class, начиная от текущего каталога.

Обратите внимание на то, что в последнем действии (7) надо указывать полное имя класса.

Если использовать ключи (options) командной строки компилятора, то можно выполнить всю работу быстрее.

1. Вызываем компилятор с ключом -d путь, указывая параметром путь начальный каталог для пакета:

javac -d classes Base.java

Компилятор создаст в каталоге classes подкаталог p1 и поместит туда три class-файла.

2. Вызываем компилятор с еще одним ключом -classpath путь, указывая параметром путь каталог classes, в котором находится подкаталог с уже откомпилированным пакетом p1:

javac -classpath classes -d classes Inp2.java

Компилятор, руководствуясь ключом -d, создаст в каталоге classes подкаталог p2 и поместит туда два class-файла, при создании которых он "заглядывал" в каталог p1, руководствуясь ключом -classpath.

3. Делаем текущим каталог classes.

4. Запускаем программу java p2.Inp2.

Для "юниксоидов" все это звучит, как музыка, ну а прочим придется вспомнить

MS-DOS.

Конечно, если вы используете для работы не компилятор командной строки, а какой-нибудь IDE, вроде Eclipse или NetBeans, то все эти действия будут сделаны без вашего участия.

На рис. 3.3 показан вывод этих действий в окно Command Prompt и содержимое каталогов после компиляции.

Рис. 3.3. Протокол компиляции и запуска программы

Импорт классов и пакетов

Внимательный читатель заметил во второй строке листинга 3.2 новый оператор import. Для чего он нужен?

Дело в том, что компилятор будет искать классы только в двух пакетах: в том, что указан в первой строке файла, и в пакете стандартных классов java.lang. Для классов из другого пакета надо указывать полные имена. В нашем примере они короткие, и мы могли бы писать в листинге 3.2 вместо Base полное имя p1. Base.