Пакети. Використання пакетів у Java. Директиви import та package. Компільовані модулі (*.java). Проміжні .class файли. Структура проекту. Використання стандартних бібліотек Java

Пакети. Використання пакетів у Java. Директиви import та package. Компільовані модулі (*.java). Проміжні .class файли. Структура проекту. Використання стандартних бібліотек Java


Зміст


1. Поняття пакету в Java

Кожен проект на мові Java у своїй роботі використовує так звані пакети. Пакет – це окремий модуль (простір імен), якому відповідає однойменний каталог (папка). Пакет містить бібліотеки (групи) класів. Ці класи об’єднані між собою в одному просторі імен або пакеті. Кількість реалізованих класів у пакеті необмежена. Класи, що оголошуються в пакеті, реалізовані у файлах з розширенням *.java.

Пакети можуть мати різноманітні рівні вкладення (підкаталоги, підпапки). На різних рівнях вкладення пакетів імена можуть повторюватись. Збереження пакетів та файлів *.java у проекті здійснюється у вигляді деревовидної структури файлової системи.

2. Як підключити пакет до існуючого проекту в Java Eclipse? Структура проекту, що містить пакети

У системі Java Eclipse підключення пакету є стандартною командою. Попередньо має бути створено проект. У проекті може розміщуватись довільна кількість пакетів. У кожному пакеті може бути довільна кількість класів.

Для створення пакету у деякому проекті використовується команда

File -> New -> Package

У результаті відкриється вікно, зображене на рисунку 1. У вікні вказується ім’я проекту та пакету, що буде розміщуватись у цьому проекті.

Рис. 1. Вікно “New Java Package“. Створення пакету з іменем MyPackage у проекті MyProject03

Після натиску на Finish відбувається наступне. Проекту з іменем MyProject03 відповідає спеціальна папка (каталог) з таким самим іменем. У цій папці створюється декілька підпапок. Одна з них підпапка з іменем src. У цій підпапці створюється папка MyPackage, що відповідає створюваному пакету.

3. Яка загальна форма виклику класу з пакету? Приклад

Щоб звернутися до імені класу з пакету використовується така загальна форма:

PackageName.ClassName

де

  • PackageName – ім’я пакету, в якому реалізований клас з іменем ClassName;
  • ClassName – ім’я класу.

Якщо пакет PackageName1 містить підпакет з іменем PackageName2, то доступ до класу з іменем ClassName має вигляд:

PackageName1.PackageName2.ClassName

Подібним чином формується доступ до класу у випадку більш складніших рівнів ієрархії.

Наприклад. Нехай задано пакет з іменем Figures. У пакеті реалізовано два класи з іменами Circle та Rectangle. Тоді, фрагмент коду, що створює об’єкти цих класів буде наступний:

// ...
Figures.Circle circle = new Figures.Circle();
Figures.Rectangle rect = new Figures.Rectangle();
// ...

4. Приклад, що демонструє використання одного імені класу у різних пакетах та у різних папках

На рисунку 2 зображено ієрархію, яку можуть утворювати пакети.

Рис. 2. У проекті MyProject03 три пакети з іменами MyPackage01, MyPackage02, MyPackage02.MyFolder02

Як видно з рисунку, у проекті MyProject03 створено 3 пакети з іменами MyPackage01, MyPackage02, MyPackage03. Кожен з пакетів має клас з однаковим іменем MyClass01. Таким чином відбувається розділення однакових імен.

Нижче наведено демонстраційний код, що створює об’єкти класів MyClass01, які розміщені у різних пакетах (папках), зображених на рисунку 2.

// 1. Створюється об'єкт класу MyClass01 з пакету MyPackage01
MyPackage01.MyClass01 mc0101 = new MyPackage01.MyClass01();

// 2. Створюється об'єкт класу MyClass01 з пакету MyPackage02
MyPackage02.MyClass01 mc0201 = new MyPackage02.MyClass01();

// 3. Створюється об'єкт класу MyClass01 з пакету MyPackage02.MyFolder02
MyPackage02.MyFolder02.MyClass01 mc020201 = new MyPackage02.MyFolder02.MyClass01();

Як видно з програмного коду, доступ до класу з пакету здійснюється з допомогою розділювача ‘ . ‘ (крапка). Щоб скоротити надто великі рядки доступу до класу, використовується директива import.

5. Яке призначення директиви import? Загальна форма. Приклад

Директива import дозволяє скоротити надто довгі рядки звертань до класів (інтерфейсів, зчислень), що реалізовані у пакетах.

У найпростішому випадку загальна форма директиви import наступна:

import PackageName.ClassFileName;

де

  • PackageName – ім‘я пакету, який підключається;
  • ClassFileName – ім‘я файлу з розширенням *.java, в якому реалізований клас або група класів, до якого потрібно звертатись за скороченим іменем.

Наприклад. Нехай у деякому проекті задано пакет Figures. У пакеті Figures реалізовано один клас з іменем Circle. Клас розміщується у файлі “Circle.java”. Вихідний код файлу Circle.java, що реалізує клас Circle, має вигляд:

// файл "circle.java"
package Figures; // пакет Figures

// клас, що описує коло на координатній площині
public class Circle
{
    double radius;
    double x, y;

    // щоб конструктор Circle() був видимий за межами
    // пакету, має бути встановлений доступ public
    public Circle()
    {
        x = y = 0;
        radius = 1;
    }

    // специфікатор доступу public обов'язковий,
    // якщо потрібно, щоб метод Set() був видимий за межами пакету
    public void Set(double x, double y, double radius)
    {
        this.x = x;
        this.y = y;
        this.radius = radius;
    }

    // метод, що повертає площу круга
    // перед методом ставиться специфікатор доступу public
    public double Area()
    {
        return 3.1415*radius*radius;
    }
}

Щоб з будь-якого іншого класу, що розміщується в іншому пакеті даного проекту, доступитись до методів файлу Circle.java з пакету Figures потрібно на початку вказати:

import Figures.Circle;

Нижче наведено приклад підключення та використання класу Circle з іншого пакету та іншого класу.

// файл "MyClass.java"
package OtherPackage;

// підключення класу Circle для скороченого звертання
import Figures.Circle;

public class MyClass 
{
    public static void main(String[] args)
    {
        // використовується скорочена форма звертання до імені класу
        Circle c = new Circle();
        double d;

        d = c.Area(); // d = 3.1415

        System.out.println("d = " + d);
    }
}

У вищенаведеному коді створюється об‘єкт класу Circle з іменем c. Однак, завдяки директиві import, назва класу вказується у природньому (скороченому) вигляді:

...

Circle c = new Circle();

...

Якщо у пакеті OtherPackage забрати рядок

import Figures.Circle;

то об‘єкт класу Circle потрібно було б створювати наступним чином

Figures.Circle c = new Figures.Circle();

 6. Як у директиві import вказати, що має бути використано усі класи з даного пакету?

Бувають випадки, коли в пакеті реалізовано декілька класів (файлів з розширенням .java) і виникає потреба підключення усієї множини класів. У цьому випадку загальна форма директиви import наступна:

import Package.*

де

  • Package – ім‘я пакету.

7. Що собою являє ключове слово package?

Ключове слово package задає ім‘я бібліотеки, в яку можуть входити різна кількість компільованих модулів. Компільовані модулі – це файли з розширенням .java.

Якщо у модулі (файл з розширенням .java) вказується рядок на зразок

package PackageName;

то це означає, що даний модуль є частиною бібліотеки з іменем PackageName.



8. Що таке компільований модуль в Java?

Кожен компільований модуль – це файл, що містить вихідний код на мові Java. Цей файл має розширення *.java. Ім‘я файлу відповідає імені відкритого (public) класу, який реалізований в цьому модулі. Ця вимога є обов‘язковою. Кожен компільований модуль має містити не більше одного відкритого класу. Компільований модуль входить до складу пакету. У пакеті може бути будь-яка кількість компільованих модулів.

9. Які вимоги до реалізації компільованого модуля (.java)?

До реалізації компільованого модуля пред‘являються наступні вимоги:

  • ім‘я компільованого модуля повинно мати розширення .java;
  • ім‘я компільованого модуля без врахування розширення .java має співпадати з іменем відкритого (public) класу, який реалізований у цьому модулі;
  • ім‘я компільованого модуля та ім‘я реалізованого в ньому відкритого класу мають починатися з великої літери;
  • у компільованому модулі має бути не більше одного відкритого (public) класу. Якщо у компільованому модулі є ще інші (допоміжні) класи, то вони мають бути прихованими (без модифікатора public).

10. Скільки класів може бути реалізовано у компільованому модулі?

Компільований модуль може мати будь-яку кількість класів. Однак, відкритим (public) має бути тільки один клас. Ім’я цього класу має співпадати з іменем компільованого модуля.

11. Яке призначення файлів з розширенням .class?

Файли з розширенням .class утворюються в результаті компіляції файлів з розширенням .java (компільованих модулів). Файли з розширенням .class є проміжними файлами, які потім об‘єднуються компоновщиком у виконавчий модуль.

Наприклад, у мові програмування Delphi тимчасові скомпільовані файли мали розширення *.dcu. У мові програмування C++ тимчасові скомпільовані файли мали розширення .obj. Потім з цих файлів утворювався *.exe файл (виконавчий модуль).

Пізніше, файли з розширенням .class об‘єднуються в пакет і стискаються утилітою JAR. Це все здійснює інтерпретатор Java.

12. Які переваги дає використання ключових слів package та import?

Використання ключових слів package та import дозволяє зручно поділити простір імен таким чином, щоб запобігти виникненню конфліктів між різними розробниками класів на Java.

13. Приклад, що демонструє структуру проекту та розміщення компільованих модулів

У Java Eclipse створено проект з іменем Project03. Проект розміщується у папці за замовчуванням, яка використовується системою Java Eclipse. У проекті створено 2 пакети з іменами Figures, OtherPackage. У пакетах реалізовано по одному компільованому модулю відповідно з іменами Circle.java та MyClass.java. Рисунок 3 відображає структуру проекту Project03 системи Java Eclipse.

Рис. 3. Відображення структури проекту Project03 у вікні Package Explorer

У файлі (модулі) Circle.java розроблено клас Circle. У файлі MyClass.java розроблено клас MyClass. У класі MyClass з пакету OtherPackage (див. рис. 3) підключається модуль Circle.java з допомогою директиви

import Figures.Circle;

Коли компілятор зустрічає директиву import, він формує повне ім‘я з врахуванням шляху до каталогу, що записаний за замовчуванням в системі.

C:\Programs\Java + \Project03\src + \Figures\Circle.java

таким чином, утворюється повне ім‘я модуля Circle.java:

C:\Programs\Java\Project03\src\Figures\Circle.java

За бажанням шлях до каталогу (папки) за замовчуванням можна змінити.

14. Приклад підключення класу зі стандартної бібліотеки Java

Щоб звернутись до імені класу зі стандартної бібліотеки Java використовується один з двох способів:

  1. Використання повної форми або повного імені класу у бібліотеці.
  2. Використання скороченої форми імені класу. У цьому випадку, повне ім’я пакету з потрібним класом, має бути задане явно з   допомогою директиви import.

Повна форма звертання до імені потрібного класу, у найпростішому випадку виглядає так

java.PackageName.ClassName

де

  • PackageName – ім’я пакету або стандартної бібліотеки Java (наприклад, util, math, applet та інші). Пакети або бібліотеки можуть мати рівні вкладення. Якщо бібліотеки містять вкладення, то вони розділяються символом ‘.’;
  • ClassName – ім’я класу (або інтерфейсу), що реалізований у бібліотеці PackageName (наприклад ArrayList, BigDecimal тощо).

Наприклад. Фрагмент коду, що використовує клас Vector зі стандартної бібліотеки Java. У даному випадку стандартна бібліотека Java має ім’я java.util.

...

// звертання до класу Vector з пакету java.util
java.util.Vector v = new java.util.Vector();

v.clear();
v.add("string - 01");
v.add("string - 02");
v.add("string - 03");

int n;
n = v.size(); // n = 3

String s;
s = (String)v.elementAt(0); // s = "string - 01"

...

У вищенаведеному коді відбувається звертання до класу Vector за повним іменем:

java.util.Vector


Зв’язані теми