CodeGym /Kursy /JAVA 25 SELF /Modyfikatory dostępu, zasięg zmiennych

Modyfikatory dostępu, zasięg zmiennych

JAVA 25 SELF
Poziom 8, Lekcja 5
Dostępny

1. Wprowadzenie

W Java, tak jak w życiu, nie wszystko powinno być dostępne dla wszystkich i zawsze. Wyobraź sobie mieszkanie: nie chcesz, aby sąsiedzi chodzili po twojej sypialni, prawda? Tak samo w programach czasem chcemy „zamknąć drzwi” do pewnych zmiennych lub metod, aby nie dało się odwołać do nich z zewnątrz.

Do tego w Java istnieją modyfikatory dostępu – specjalne słowa, które określają, gdzie można używać danej zmiennej lub metody: na przykład public lub private.

Główne modyfikatory dostępu

Modyfikator Gdzie widoczne?
public
Wszędzie, gdzie klasa jest widoczna (zarówno w innych pakietach, jak i w innych plikach)
private
Tylko wewnątrz tej samej klasy
(bez modyfikatora)
Tylko w obrębie tego samego pakietu (tzn. w klasach w tym samym katalogu)

Istnieją też inne modyfikatory, ale poruszymy je później, gdy dojdziemy do dziedziczenia.

Przykład w praktyce

public class User 
{
    public String name;           // widoczne dla wszystkich
    private int age;              // widoczne tylko wewnątrz klasy User

    public void sayHello() 
    {
        System.out.println("Cześć, nazywam się " + name);
    }

    private void secretMethod() 
    {
        System.out.println("To tajna metoda!");
    }
}

Wyjaśnienie:

  • name – widoczne wszędzie, gdzie można użyć klasy User.
  • age – widoczne tylko wewnątrz samej klasy User.
  • sayHello() – metoda publiczna, można ją wywołać z dowolnej innej klasy.
  • secretMethod() – metoda prywatna, nie można jej wywołać z zewnątrz.

Jak to działa w prawdziwych zadaniach?
Załóżmy, że mamy klasę opisującą konto bankowe. Zdecydowanie nie chcemy, aby każdy mógł bezpośrednio zmieniać saldo! Dlatego zmienna salda będzie private, a do pracy z nią będą służyć specjalne metody.

Dlaczego nie należy robić wszystkiego public?

Może pojawić się pokusa: „A zróbmy wszystko public, żeby się nie męczyć!” Ale to droga do chaosu. Wyobraź sobie, że każdy może zmieniać twoje saldo, nazwę użytkownika, a nawet wywoływać metodę przeznaczoną tylko do użytku wewnętrznego. W dużych programach prowadzi to do błędów i „magicznych” problemów.

Złota zasada programisty Java:
Najpierw ustawiaj wszystko jako private, a potem udostępniaj na zewnątrz tylko to, co naprawdę potrzebne.

2. Zasięg zmiennych

Zasięg to obszar kodu, w którym zmienna „istnieje” i może być użyta. Po wyjściu poza ten obszar zmienna „znika” – jakby jej nie było.

W Java istnieje kilka rodzajów zmiennych według zasięgu:

  • Zmienne lokalne – zadeklarowane wewnątrz metody lub bloku kodu { ... }.
  • Parametry metody – zadeklarowane w nawiasach okrągłych metody.
  • Pola klasy – zadeklarowane wewnątrz klasy, ale poza metodami.

Jeśli zmienna została zadeklarowana wewnątrz { bloku },
jest widoczna tylko wewnątrz tego bloku
i niedostępna poza nim.
Zasięg zmiennej lokalnej

Zmienne lokalne

Zmienna lokalna „żyje” tylko wewnątrz metody lub bloku, w którym została zadeklarowana.

void printSum(int a, int b) 
{
    int sum = a + b; // zmienna lokalna
    System.out.println(sum);
}
// sum nie istnieje już w tym miejscu!

Próba odwołania się do sum poza metodą spowoduje błąd kompilacji: „Nie można znaleźć zmiennej sum”.

Parametry metody

Parametry to też zmienne, ale żyją tylko wewnątrz metody.

void greet(String name) 
{
    System.out.println("Cześć, " + name);
}
// name nie istnieje już w tym miejscu!

Pola klasy (pola składowe)

Pola klasy deklaruje się wewnątrz klasy, ale poza metodami. Są widoczne we wszystkich metodach tej klasy.

public class Counter 
{
    private int count = 0; // pole klasy

    public void increment() 
    {
        count++; // możemy używać pola
    }

    public int getCount() 
    {
        return count; // również możemy używać pola
    }
}

3. Przesłanianie zmiennych (shadowing)

Przesłanianie (shadowing) to sytuacja, gdy w jednej przestrzeni nazw (zasięgu) deklaruje się zmienną (lub parametr) o tej samej nazwie, co w zewnętrznym zasięgu. Wewnątrz takiego bloku „nowa” nazwa przesłania starszą i do zewnętrznej wartości nie można odwołać się bezpośrednio.

Przykład przesłaniania:

class ShadowDemo 
{
    int value = 10; // pole klasy

    void printValue() 
    {
        System.out.println(value);  // 10 – wypisuje pole klasy
        int value = 5; // zmienna lokalna przesłania pole klasy
        System.out.println(value); // wypisuje 5, a nie 10
    }
}

W tym przykładzie, gdy piszemy int value = 5;, deklarujemy nową zmienną lokalną, która ma priorytet nad polem klasy o tej samej nazwie. Przy odwołaniu do value wewnątrz metody printValue() będzie używana zmienna lokalna, a nie pole klasy.

Jeśli jednak trzeba odwołać się do statycznego pola klasy, użyj nazwy klasy jako prefiksu:

class ShadowDemo 
{
    static int value = 10; // statyczne pole klasy 

    void printValue() 
    {
        System.out.println(value);      // 10 – pole klasy
        int value = 5;
        System.out.println(value);      // 5 – zmienna lokalna
        System.out.println(ShadowDemo.value); // 10 – statyczne pole klasy, dostęp przez 'ShadowDemo'
    }
}

Jeśli chcesz odwołać się do niestatycznego pola klasy, używa się słowa kluczowego this. Wskazuje ono na bieżącą instancję obiektu.

class ShadowDemo 
{
    int value = 10;

    void printValue() 
    {
        System.out.println(value);      // 10 – pole klasy
        int value = 5;
        System.out.println(value);      // 5 – zmienna lokalna
        System.out.println(this.value); // 10 – pole klasy, dostęp przez 'this'
    }
}

4. Praktyka: modyfikatory dostępu i zasięg

Kontynuujmy rozwijanie aplikacji edukacyjnej: prosta ewidencja studentów. Zastosujemy różne modyfikatory dostępu dla pól i metod.

Przykład: klasa Student

public class Student 
{
    public String name;        // imię studenta (widoczne dla wszystkich)
    private int age;           // wiek (widoczny tylko wewnątrz klasy)

    public Student(String name, int age) 
    {
        this.name = name;
        this.age = age;
    }

    public void sayHello() 
    {
        System.out.println("Cześć, nazywam się " + name);
    }

    private void printSecret() 
    {
        System.out.println("Mój wiek: " + age);
    }

    public void revealSecret() 
    {
        printSecret(); // można wywołać metodę prywatną wewnątrz klasy
    }
}

Użycie klasy Student

public class Main 
{
    public static void main(String[] args) 
    {
        Student s = new Student("John", 20);
        s.sayHello();       // OK: metoda publiczna
        s.revealSecret();   // OK: metoda publiczna, która wewnątrz wywołuje prywatną

        s.age = 30;      // Błąd! Pole age jest prywatne

        s.printSecret(); // Błąd! Metoda printSecret jest prywatna
    }
}

5. Typowe błędy przy pracy z modyfikatorami dostępu i zasięgiem

Błąd nr 1: Wszystko public – i witaj, chaosie!
Jeśli wszystkie pola i metody będą publiczne, ryzykujesz utratę kontroli nad tym, kto i jak zmienia twoje dane. Ustawiaj pola jako private i udostępniaj na zewnątrz tylko to, co niezbędne.

Błąd nr 2: Próba użycia zmiennej poza jej zasięgiem.
Na przykład zadeklarowano zmienną wewnątrz metody, a potem próbuje się odwołać do niej z zewnątrz – pojawi się błąd kompilacji. Zmienne lokalne żyją tylko w swoim bloku { ... }.

Błąd nr 3: Konflikt nazw (przesłanianie zmiennych).
Jeśli w metodzie zadeklarujesz zmienną o tej samej nazwie, co pole klasy, łatwo się pomylić, której zmiennej używasz. Używaj this, aby jednoznacznie wskazać pole klasy: this.value.

Błąd nr 4: Próba odwołania się do metody private lub pola z innej klasy.
Jeśli metoda lub pole są oznaczone jako private, są dostępne tylko wewnątrz tej samej klasy. Próba odwołania z zewnątrz spowoduje błąd kompilacji.

Błąd nr 5: Zapomniany zasięg w pętli lub bloku.
Zmienna zadeklarowana wewnątrz pętli albo dowolnego bloku { } żyje tylko wewnątrz tego bloku. Poza nim nie istnieje.

1
Zadanie
JAVA 25 SELF, poziom 8, lekcja 5
Niedostępne
Otwarty rejestr mieszkańców wsi 🏡
Otwarty rejestr mieszkańców wsi 🏡
1
Zadanie
JAVA 25 SELF, poziom 8, lekcja 5
Niedostępne
Ściśle tajne konto bankowe klienta 🔒
Ściśle tajne konto bankowe klienta 🔒
1
Zadanie
JAVA 25 SELF, poziom 8, lekcja 5
Niedostępne
Ustawianie rozmiaru pudełka produkcyjnego 📦
Ustawianie rozmiaru pudełka produkcyjnego 📦
1
Zadanie
JAVA 25 SELF, poziom 8, lekcja 5
Niedostępne
Zarządzanie informacjami o uczniach w bazie danych 👩‍🎓
Zarządzanie informacjami o uczniach w bazie danych 👩‍🎓
1
Ankieta/quiz
Metody, poziom 8, lekcja 5
Niedostępny
Metody
Deklaracja i wywołanie metod
Komentarze
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION