Sobes.tech
Junior

Czym jest widoczność w kontekście programowania w Java?

sobes.tech AI

Odpowiedź od AI

Widoczność w kontekście Java (zwany także zakresem widoczności) określa dostępność zmiennej, metody, konstruktora lub klasy z innych części programu. Jest kontrolowana przez modyfikatory dostępu.

W Java istnieją cztery poziomy widoczności:

  1. public: Dostępny z dowolnego miejsca wewnątrz i na zewnątrz pakietu.
  2. protected: Dostępny wewnątrz tego samego pakietu i w podklasach (nawet w innych pakietach).
  3. Tryb domyślny (default lub package-private): Dostępny tylko wewnątrz tego samego pakietu. Nie jest jawnie określany modyfikatorem.
  4. private: Dostępny tylko wewnątrz tej samej klasy.
Modyfikator Klasa Pakiet Podklasa (poza pakietem) Dowolna klasa (poza pakietem)
public Tak Tak Tak Tak
protected Tak Tak Tak Nie
Domyślny Tak Tak Nie Nie
private Tak Nie Nie Nie

Użycie modyfikatorów widoczności odgrywa ważną rolę w enkapsulacji i kontroli dostępu do elementów programu.

Przykład użycia modyfikatorów:

// Klasa A w pakiecie com.example.package1
package com.example.package1;

public class ClassA {
    public int publicVar;
    protected int protectedVar;
    int defaultVar; // Modyfikator domyślny
    private int privateVar;

    public void publicMethod() {
        // Może uzyskać dostęp do wszystkich zmiennych klasy ClassA
        System.out.println("Metoda publiczna w ClassA");
    }

    protected void protectedMethod() {
        System.out.println("Metoda chroniona w ClassA");
    }

    void defaultMethod() {
        System.out.println("Metoda domyślna w ClassA");
    }

    private void privateMethod() {
        System.out.println("Metoda prywatna w ClassA");
    }

    public void accessMembers() {
        publicVar = 1;
        protectedVar = 2;
        defaultVar = 3;
        privateVar = 4; // OK, dostęp w klasie
        privateMethod(); // OK, dostęp w klasie
    }
}
// Klasa B w tym samym pakiecie com.example.package1
package com.example.package1;

public class ClassB {
    public void accessClassAMembers(ClassA objA) {
        objA.publicVar = 10; // OK, publiczny
        objA.protectedVar = 20; // OK, chroniony (ten sam pakiet)
        objA.defaultVar = 30; // OK, domyślny (ten sam pakiet)
        // objA.privateVar = 40; // Błąd kompilacji, prywatny
        objA.publicMethod(); // OK, publiczny
        objA.protectedMethod(); // OK, chroniony (ten sam pakiet)
        objA.defaultMethod(); // OK, domyślny (ten sam pakiet)
        // objA.privateMethod(); // Błąd kompilacji, prywatny
    }
}
// Klasa C w innym pakiecie com.example.package2
package com.example.package2;
import com.example.package1.ClassA;

public class ClassC extends ClassA { // ClassC jest podklasą ClassA
    public void accessClassAMembersFromSubclass() {
        publicVar = 100; // OK, publiczny
        protectedVar = 200; // OK, chroniony (podklasa, nawet w innym pakiecie)
        // defaultVar = 300; // Błąd kompilacji, domyślny (inny pakiet)
        // privateVar = 400; // Błąd kompilacji, prywatny

        publicMethod(); // OK, publiczny
        protectedMethod(); // OK, chroniony (podklasa, nawet w innym pakiecie)
        // defaultMethod(); // Błąd kompilacji, domyślny (inny pakiet)
        // privateMethod(); // Błąd kompilacji, prywatny
    }
}
// Klasa D w innym pakiecie com.example.package2 (NIE podklasa ClassA)
package com.example.package2;
import com.example.package1.ClassA;

public class ClassD {
    public void accessClassAMembers(ClassA objA) {
        objA.publicVar = 1000; // OK, publiczny
        // objA.protectedVar = 2000; // Błąd kompilacji, chroniony (inny pakiet, nie podklasa)
        // objA.defaultVar = 3000; // Błąd kompilacji, domyślny (inny pakiet)
        // objA.privateVar = 4000; // Błąd kompilacji, prywatny

        objA.publicMethod(); // OK, publiczny
        // objA.protectedMethod(); // Błąd kompilacji, chroniony (inny pakiet, nie podklasa)
        // objA.defaultMethod(); // Błąd kompilacji, domyślny (inny pakiet)
        // objA.privateMethod(); // Błąd kompilacji, prywatny
    }
}

Zrozumienie widoczności pomaga tworzyć bardziej niezawodny i modułowy kod, ograniczając niepożądany dostęp do wewnętrznych szczegółów klas.