Modyfikatory dostępu w Javie

Poprzednio przyjrzeliśmy się bliżej metodom, konstruktorom oraz sposobom przekazywania danych do metod.

Modyfikatory dostępu do pól

W dzisiejszej lekcji skupimy się na modyfikatorach dostępu klas, metod oraz pól. Zaczniemy od ich wylistowania.

  • public – oznacza widoczność bez ograniczeń.
  • protected – widoczność w obrębie klas dziedziczonych.
  • private – widoczność tylko w obrębie danej klasy.
  • brak modyfikatora dostępu – widoczność w obrębie danego pakietu.

Modyfikatory dostępu określają widoczność elementów, takich jak pola, metody, klasy i interfejsy. To od nich zależy w jaki sposób można uzyskać dane oraz czy będą bezpieczne. Z modyfikatorami dostępu dużo wspólnego ma zasada hermetyzacji danych. Poniżej przyjrzymy się bliżej co konkretne słowo oznacza w różnych przypadkach.

Modyfikator public

Ten modyfikator zapewnia swobodny dostęp do elementu – klasy, interfejsu, pola lub metody. Ogólnie możemy przyjąć, że metody w Javie powinny być publiczne. Natomiast jeśli jakaś metoda będzie użyta wyłącznie w obrębie danej klasy można nadać jej modyfikator private. Podobnie jeśli chcemy ukryć tę metodę, aby nie była widoczna przy działaniu na obiekcie w innej klasie.

Modyfikator public a zachowanie pól

Poniżej pokażemy przykład jak w praktyce modyfikator public wpływa na zachowanie pól w klasie.

Przy użyciu modyfikatora public możemy bezpośrednio wpisywać i pobierać wartości z obiektu. Czemu zatem na siłę utrudniać sobie życie i nie uczynić wszystkich pól publicznych? Ponieważ w ten sposób złamiemy zasadę hermetyzacji danych.

Jak widać powyżej chcąc wyświetlić zmodyfikowaną wartość przez przypadek została zmodyfikowana wartość w obiekcie.

Modyfikator public przy metodach

Skupmy się teraz na modyfikatorze metody. Na powyższym przykładzie mamy dwie klasy – Main i Samochod. Dzięki temu, że metoda pokazPrzebieg() jest publiczna możemy jej użyć na obiekcie, który znajduje się w ciele metody main() w klasie Main.

Co by się zmieniło gdyby przed metodą zamiast modyfikatora public napisać private? Otóż metoda byłaby widoczna jedynie w obrębie klasy Samochod i nie można byłoby wywołać jej w klasie Main.

Modyfikator private

Ten modyfikator jest przeciwieństwem public, gdyż jest najbardziej restrykcyjny jeśli chodzi o dostęp do danych. Dostęp do danych wymaga specjalnych metod. Nie można go stosować do klas poza jednym wyjątkiem – klas wewnętrznych.

Modyfikator private a dostęp do pól

Zamieńmy teraz modyfikator w polu przebieg i zobaczmy jak on wpłynie na działanie programu.

W przypadku próby dostępu do pola przebieg bezpośrednio bez użycia metody pokazPrzebieg() kompilator zwróci błąd.

Modyfikacja oraz dostęp do pól prywatnych

Jak zatem zapisać wartość w polu o tak restrykcyjnym modyfikatorze dostępu? Należy użyć metody, która to zrobi i wywołać ją na rzecz danego obiektu (tzw. getter lub setter). Poniższy listing pokaże przykładową implementację takiej metody.

Oczywiście możemy ją opracować w inny sposób np. dodając wartość podaną w argumencie.

Metoda dostępu różni się tym, że musi zwracać wartość typu, którego jest pole.

Modyfikator private dla metod

W przypadku użycia modyfikatora private do metody będzie do niej dostęp będzie widoczny jedynie w obrębie danej klasy. Jest to wygodne rozwiązanie, gdy nie chcemy, aby ktoś mógł wywołać metodę poza konkretną klasą.

Modyfikator protected

Wykorzystywany jest w przypadku dziedziczenia i dostępie z klas podrzędnych (podklas). Zrozumienie tego modyfikatora wymaga poznania pojęcia dziedziczenia – czyli jednego z filarów paradygmatu programowania obiektowego. Spójrzmy na poniższy kod.

Modyfikator protected a dostęp do pól

Dzięki zastosowaniu modyfikatora protected w podklasie można zdefiniować metodę, która się do pola zdefiniowanego w nadklasie.

Modyfikator protected dla metod

Podobnie jak w przypadku pól zachowuje się widoczność metod. W podklasie można z nich korzystać, a nawet przesłonić własną definicją. Aby wywołać metodę z nad klasy należy użyć słowa kluczowego super.

Gdybyśmy nie użyli słowa kluczowego super, to metoda wywołałaby samą siebie, a więc wywoła się rekurencyjnie. Rezultatem będzie przepełnienie stosu oraz błąd StackOverflowError.

Tego modyfikatora nie można użyć przed klasą.

Brak modyfikatora dostępu

W przypadku pominięcia uzupełnienia modyfikatora dostęp do danych będzie widoczny wyłącznie w obrębie pakietu, co bywa problematyczne i nie jest zalecane.

Podobnie jest w przypadku klas – gdy znajdują się w innych pakietach nie są dla siebie widoczne – nawet jeśli zaimportujemy pakiet.

Porady do używania modyfikatorów dostępu

Zazwyczaj należy stosować zasadę, że wszystkie pola i metody, które są wykorzystywane wyłącznie w klasie powinny być prywatne, a pozostałe metody i klasy – publiczne.

Pakiety

Pakiety podobnie jak foldery są jednostką porządkującą. Ułatwiają znalezienie konkretnej klasy oraz zwalniają z obowiązku pilnowania czy klasa nie znajduje się już w jakiejś bibliotece. Jeśli klasa o tej samej nazwie znajduje się w dwóch różnych pakietach, to nie wystąpi żaden konflikt nazw. Do przypisania klasy do pakietu służy słowo kluczowe package.

Słowo kluczowe import

Jeżeli chcemy skorzystać z osobnego pakietu (klasy są widoczne w obrębie jednego pakietu), to należy zaimportować inny pakiet słowem import.

Zaimportować można zarówno cały pakiet korzystając z operatora * lub konkretną klasę – wtedy należy napisać całą nazwę pakietu i klasy.

Import całej biblioteki java.util nie wpływa negatywnie na rozmiar kodu, ani na wydajność. Natomiast utrudnia zidentyfikowanie, które klasy zostały użyte w programie.

Konflikt nazw

Jeśli w naszym pakiecie zaimplementujemy klasę o tej samej nazwie, która znajduje się w innym pakiecie, to kompilator będzie miał problem z użyciem odpowiedniej klasy. W związku z tym należy wskazać kompilatorowi za każdym razem klasę, którą chcemy użyć. Załóżmy, że w naszym pakiecie mamy klasę Scanner, która robi inną rzecz niż na z biblioteki java.util. Poniższy listing pokaże jak użyć odpowiedniej klasy.

Nazewnictwo pakietów

Aby nie spodować konfliktu nazw warto stosować się do konwencji nazewczniczej. domena.mudułAplikacji np.

pl.programistajava.samochod

Wszystkie pakiety z biblioteki standardowej znajdują się w pakietach java i javax.

W kolejnej części przyjrzymy się słowu kluczowemu static oraz metodzie main.