Modyfikatory dostępu

W Javie istnieją 4 modyfikatory (nazywane też specyfikatorami) dostępu, które pozwalają kontrolować poziom dostępu do klas, interfejsów oraz ich składowych. Dzięki nim możemy określić, czy jakiś element ma być widoczny tylko w typie, w którym się znajduje, na poziomie pakietu, czy całego projektu oraz poza nim.

Cztery specyfikatory, które omówimy to private, domyślny (package private), protected oraz default.

Kurs Java

private

W przypadku użycia modyfikatora private ograniczamy dostęp tylko do klasy w której znajduje się wskazany element.

Poniżej przykład pokazuje zmienną number widoczną tylko w ramach klasy MyClass

public class MyClass {

    private int number = 10;

    void printNumberExternal() {
        System.out.println(number);
    }

    private class InternalClass {

        void alsoPrintNumber() {
            System.out.println(number);

            printNumberExternal();
        }
    }

}

Pomimo, że specyfikator private jest najbardziej restrykcyjny, to jednocześnie powinien być traktowany jako bardziej użyteczny. Warto kierować się zasadą, że dopóki coś nie musi być dostępne poza klasą, to powinno to być prywatne. Powiemy o takich elementach, że stanowią detal implementacyjny danej klasy. Modyfikator private jest też użyteczny do podziału metod na mniejsze fragmenty i podczas refaktoryzacji, dzięki czemu pozwala m.in. na zachowanie zasady pojedynczej odpowiedzialności.

domyślny (package private)

W przypadku gdy nie podamy żadnego modyfikatora użyty zostanie domyślnie package private. Oznaczony element widoczny będzie tylko w ramach tego samego pakietu. Modyfikator domyślny jest raczej rzadko wykorzystywany, a warto po niego sięgać jako domyślnego specyfikatora dla klas. Dzięki temu możemy z pakietów tworzyć swego rodzaju moduły.

protected

Elementy oznaczone jako protected widoczne są w ramach tego samego pakietu, oraz dodatkowo w klasach dziedziczących, które mogą się znajdować w innych pakietach. Jeżeli mamy więc w pakiecie "a" klasę Foo, a w pakiecie "b" klasę Bar, która dziedziczy po Foo, to poprawny jest poniższy kod:

package a;

public class Foo {
    protected int x = 5;
}
package b;

import a.Foo;

public class Bar extends Foo {
    int y = 10;

    void showSum() {
        System.out.println(x + y);
    }
}

Używając specyfikatora domyślnego, zamiast protected, otrzymalibyśmy błąd kompilacji.

public

Specyfikator public wskazuje, że do danego typu (klasy, interfejsu, typu wyliczeniowego) można się odwoływać z dowolnego innego pakietu w ramach projektu lub poza nim. Tworząc nową klasę, czy interfejs korzystając z popularnych środowisk programistycznych, będą one miały najczęściej zastosowany właśnie specyfikator public. Warto zmienić to w ustawieniach i wykorzystywać do tego celu specyfikator domyślny. Pozwoli to na wprowadzenie enkapsulacji nie tylko na poziomie kodu, ale także na poziomie struktury projektu.

Dyskusja i komentarze

Masz pytania do tego wpisu? Może chcesz się podzielić spostrzeżeniami? Zapraszamy dyskusji na naszej grupie na Facebooku.