Pakiety klas

 

Pakiet to grupa powiązanych klas (typów) z określnymi modyfikatorami dostępu. Użycie pakietów zapewnia możliwość zarządzania określonymi przestrzeniami nazw - każdy pakiet stanowi odrębną przestrzeń nazw.

 

Klasy dostępne na platformie Java są pogrupowane w pakiety. Np. klasy podstawowe znajdują się w pakiecie java.lang, klasy odpowiedzialne za operacje we/wy znajdują się w pakiecie java.io.

 

Dla wygody, kompilator Javy zawsze domyślnie, automatycznie importuje dla każdego pliku źródłowego następujące dwa całe pakiety klas:

  • pakiet java.lang, w którym znajdują się najczęściej używane klasy;
  • bieżący pakiet (pakiet bieżącego pliku - aktualnie kompilowanego pliku) - czyli importowane są wszystkie klasy z katalogu, w którym znajduje się aktualnie kompilowany plik.
  • ponadto importowane są wszystkie pakiety, które wystąpią w instrukcjach "import nazwa.pakietu..." napotkanych w kompilowanych plikach.

 

Dlaczego warto używać umieszczać klasy w pakietach...

  • aby ułatwić wyszukiwanie i używanie klas przez odpowiednie grupowanie klas pokrewnych;
  • aby uniknąć konfliktu nazw klas z odrębnych pakietów, gdy w różnych pakietach wystąpią klasy o takiej samej nazwie; łatwo wyobrazić sobie sytuację, w której będziesz chciał użyć klasy o nazwie Rectangle; jednakże istnieje już klasa Javy o takiej nazwie w pakiecie java.awt; dzięki mechanizmowi pakietów możesz utworzyć własną klasę Rectangle, która będzie odróżniana od klasy java.awt.Rectangle;
  • aby zapewnić kontrolę dostępu do poszczególnych klas, pozwalając np. na nieograniczony wzajemny dostęp klasom z jednego pakietu, lecz ograniczając dostęp dla klas spoza pakietu.

 

Użycie klas bez określania pakietów ma uzasadnienie wyłącznie w wypadku bardzo małych lub tymczasowych programów. W każdej innej sytuacji warto i należy używać pakietów o określonych nazwach.

 

Konwencja dotycząca nazw pakietów

Aby utworzyć pakiet, koniecznie musisz określić nazwę pakietu.

Obowiązują następujące zasady dotyczące nazw pakietów:

  • nazwy pakietów zaczynają się od małej litery, aby nie wystąpił konflikt z nazwami klas lub interfejsów,
  • zgodnie z ogólnymi zasadami nazw Java nazwa pakietu nie może zaczynać się od cyfry; jeśli chcesz rozpocząć nazwę swojego pakietu od cyfry, poprzedź ją znakiem podkreślenia (underscore) - np. _123nazwapakietu.;
  • nazwa pakietu nie może być żadnym zarezerwowanym słowem kluczowym Javy - np. użycie pakietu o nazwie int. jest niedozwolone; możesz jednak użyć nazwy _int. lub int_.;
  • nazwy pakietów zarezerwowane dla klas języka Java to java. oraz javax.;
  • zwyczajowo firma o adresie internetowym nazwafirmy.com zaczyna nazwy swoich pakietów oprogramowania od com.nazwafirmy., a dalej dodaje nazwy wewnętrznych-firmowych pakietów, aby uniknąć konfliktu nazw w firmowym oprogramowaniu;
  • w nazwach pakietów nie mogą występować żadne znaki specjalne ani interpunkcyjne; zamiast myślnika użyj znaku podkreślenia - czyli np. w wypadku domeny nazwa-firmy.com użyj nazwy pakietu com.nazwa_firmy..

 

Gdy już określisz nazwę swojego pakietu zgodnie z opisaną wyżej konwencją, wykonaj następujące kroki:

1. w swoim katalogu roboczym utwórz podkatalog o nazwie twoja.nazwa.pakietu,

2. utwórz lub umieść w tym katalogu plik zawierający kod definicji twojej klasy,

3. na samym początku pliku zawierającego kod definicji twojej klasy wpisz widoczny niżej pierwszy wiersz:

package twoja.nazwa.pakietu;

class TwojaKlasa {
    ...
}

 

 

Korzystanie z klas należących do pakietów

 

Kompilator Javy widzi tylko bieżący folder, jego podfoldery oraz wszystkie foldery zapisane w zmiennej środowiskowej CLASS_PATH. Aby w bieżącym katalogu, w którym uruchamiasz narzędzie javac, był dostępny określony pakiet, pakiet ten musi występować w formie podkatalogu w katalogu bieżącym lub w dowolnym katalogu wskazanym w zmiennej środowiskowej CLASS_PATH.

Aby w klasie/obiekcie spoza pakietu użyć klasy należącej do określonego pakietu, należy wykonać jedną z trzech czynności:

  • uzyskać dostęp do klasy przy użyciu w pełni kwalifikowanej nazwy składającej się z nazwy pakietu oraz nazwy klasy,

    PRZYKŁAD deklaracji zmiennej klasy Color z pakietu java.awt i zainicjowania tej zmiennej przy użyciu konstruktora klasy java.awt.Color:

    java.awt.Color color = new java.awt.Color( 0, 0, 0 );
  • zaimportować klasę z pakietu:
    import java.awt.Color;
    
    class MojaKlasa{
        Color color = new Color( 0, 0, 0 );    // Klasa Color z pakietu java.awt. jest dostępna, ponieważ została zaimportowana
        ...
    }
  • zaimportować cały pakiet:
    import java.awt.*;
    
    class MojaKlasa{
        Color color = new Color( 0, 0, 0 );    // Klasa Color z pakietu java.awt jest dostępna, ponieważ został zaimportowany cały pakiet
        ...
    }

 

 

Importowanie klas zagnieżdzonych

Aby zaimportować wszystkie klasy zagnieżdżone/wewnętrzne zdefiniowane wewnątrz np. klasy Outer, użyj następującej instrukcji:

import nazwa.pakietu.Outer.*;

Taka instrukcja nie zaimportuje klasy Outer, lecz wszystkie jej klasy wewnętrzne/zagnieżdżone. Aby zaimportować także klasę Outer, należy użyć następujących dwóch instrukcji:

import nazwa.pakietu.Outer;
import nazwa.pakietu.Outer.*;

 

 

Hierarchia pakietów

Jeśli na przykład wewnątrz pakietu java.awt. znajdją się pakiety podrzędne np. java.awt.color, java.awt.font, pakiety te nie są importowane po użyciu instrukcji

import java.awt.*;

Aby zaimportować pakiety java.awt.color i java.awt.font, należy użyć dla każdego z nich osobnej instrukcji. Np.:

import java.awt.*;
import java.awt.color.*;
import java.awt.font.*;

 

 

Dwuznaczność nazw

Jeśli zaimportujesz dwa pakiety, w których występują dwie lub więcej klas o takiej samej nazwie, wówczas należy w wypadku obu klas użyć w pełni kwalifikowanych nazw składających się z nazwy pakietu oraz nazwy klasy. Załóżmy, że utworzyłeś pakiet my.package, a w nim klasę Rectagle, zaimportowałeś go, a także zaimportowałeś pakiet java.awt, w którym również występuje klasa o nazwie Rectangle. W takiej sytuacji za każdym razem, gdy używasz klasy Rectangle, musisz określić, której klasy chcesz użyć w danym miejscu, podając pełną nazwę pakietu - w następujący sposób:

import my.package.*;
import java.awt.*;

class MyClass {
    my.package.Rectangle myRectange = new my.package.Rectangle();
    java.awt.Rectangle awtRectangle = new java.awt.Rectangle();
}

 

 

Importowanie metod statycznych

Istnieje możliwość zaimportowania wszystkich metod statycznych danej klasy, aby nie było konieczne wywoływanie tych metod przy użyciu nazwy klasy. Świetnym przykładem jest klasa Math z pakietu java.lang. Standardowo kompilator Javy automatycznie importuje pakiet java.lang. Dlatego nie musisz go importować jawnie w swoich programach. Jednakże aby wywołać funkcje matematyczne, musisz za każdym razem przed nazwą funkcji dodać nazwę klasy Math w następujący sposób:

double wynik = Math.sqrt( 9 );

Możesz też jawnie zaimportować wszystkie statyczne metody klasy Math i wówczas będziesz mógł wywołać funkcje matematyczne w następujący sposób:

import static java.lang.Math.*;

...

        double wynik = sqrt( 9 );

Poprawi to przejrzystość kodu i ułatwi pisanie programu.

 

 

Kompilacja kodu korzystającego z pakietów

Jeśli struktura katalogów pakietów jest umieszczona w bieżącym katalogu, w którym znajduje się kompilowany plik zawierający dyrektywę importu pakietu/pakietów, wówczas kompilator automatycznie wyszuka pliki importowanych pakietów. Jeśli natomiast katalogi z pakietami znajdują się w innym miejscu, wówczas używając narzędzia javac należy zastosować parametr -cp z nazwą katalogu, w którym znajdują się odpowiednie pliki .class lub odpowiadające im pliki .java. Nazwa katalogu może być określona bezwzględnie lub względem katalogu bieżącego.

Ponadto warto oddzielić strukturę katalogów z plikami źródłowymi .java od katalogów z wynikowymi plikami kompilacji - plikami .class. Wówczas możliwe będzie udostępnienie twioch programów w formie kodu bajtowego bez udostępniania plików źródłowych z kodem w języku Java. Aby to zrobić, użyj narzędzia javac z opcją -d i nazwą katalogu, w którym mają znaleźć się wygenerowane pliki .class.