Modificatori de acces (public, protected, private) în Java

public, protected, private și lipsa modificatorului stabilesc cine poate vedea o clasă, un câmp, o metodă sau un constructor.

Sintaxă
public class Cont {          // vizibilă de oriunde
    private double sold;     // doar în clasa Cont
    protected String banca;  // pachet + subclase
    String iban;             // fără modificator: doar în pachet

    public double getSold() { return sold; }
}

Ce face Modificatori de acces (public, protected, private)

Java are patru niveluri de acces, de la cel mai larg la cel mai strict: public (oriunde), protected (în același pachet și în subclase, chiar din alte pachete), fără modificator, numit și „package-private” (doar în același pachet) și private (doar în interiorul clasei care declară membrul).

Regula obișnuită este încapsularea: câmpurile sunt private, iar accesul se face prin metode public care pot verifica datele (getteri, setteri, operații precum depune). Astfel nimeni din afară nu poate pune obiectul într-o stare invalidă, de exemplu un sold negativ.

O clasă de nivel superior poate fi doar public sau fără modificator, și cel mult una public per fișier. Clasele interne pot avea oricare din cele patru niveluri. Accesul se verifică la compilare: dacă nu ai voie, codul nu compilează.

Parametri

Parametru Descriere
public Accesibil de oriunde.
protected În același pachet și în subclase (și din alte pachete, prin moștenire).
(niciunul) Doar în același pachet.
private Doar în clasa care îl declară (inclusiv clasele ei interne).

Exemple

Exemplul 1: Câmpuri private și metode publice

Soldul este private: din Main nu se poate scrie cont.sold = -500. Singurele căi sunt metodele publice, care verifică suma.

class ContBancar {
    private final String titular;
    private double sold;

    public ContBancar(String titular) {
        this.titular = titular;
    }

    public void depune(double suma) {
        if (suma <= 0) {
            System.out.println("Suma trebuie să fie pozitivă.");
            return;
        }
        sold += suma;
    }

    public boolean retrage(double suma) {
        if (suma > sold) {
            System.out.println("Fonduri insuficiente pentru " + suma + " lei.");
            return false;
        }
        sold -= suma;
        return true;
    }

    public double getSold() {
        return sold;
    }

    public String getTitular() {
        return titular;
    }
}

public class Main {
    public static void main(String[] args) {
        ContBancar cont = new ContBancar("Andreea Popa");
        cont.depune(1200);
        cont.depune(-50);
        cont.retrage(2000);
        cont.retrage(300);
        System.out.println(cont.getTitular() + ": " + cont.getSold() + " lei");
        // cont.sold = -500;  // nu compilează: sold has private access in ContBancar
    }
}

Rezultat

Suma trebuie să fie pozitivă.
Fonduri insuficiente pentru 2000.0 lei.
Andreea Popa: 900.0 lei

Exemplul 2: protected pentru subclase

Vehicul lasă câmpul viteza protected, ca subclasa Masina să îl poată modifica, și metoda ajutătoare private, folosită doar intern.

class Vehicul {
    protected int viteza;
    private int pornit;

    public void porneste() {
        pornit++;
        jurnal("pornire nr. " + pornit);
    }

    private void jurnal(String mesaj) {
        System.out.println("[" + getClass().getSimpleName() + "] " + mesaj);
    }
}

class Masina extends Vehicul {
    public void accelereaza(int cu) {
        viteza += cu;             // protected: vizibil în subclasă
        if (viteza > 130) {
            viteza = 130;
        }
    }
}

public class Main {
    public static void main(String[] args) {
        Masina m = new Masina();
        m.porneste();
        m.accelereaza(90);
        m.accelereaza(60);
        System.out.println("viteza: " + m.viteza + " km/h");
    }
}

Rezultat

[Masina] pornire nr. 1
viteza: 130 km/h

Greșeli frecvente

  • Faci toate câmpurile public „ca să meargă”. Orice cod le poate modifica fără verificare; păstrează-le private și expune doar operațiile necesare.
  • Accesezi un membru private din altă clasă: sold has private access in ContBancar.
  • Pui public pe două clase din același fișier: class Masina is public, should be declared in a file named Masina.java.
  • Crezi că protected este mai strict decât lipsa modificatorului. E invers: protected include tot pachetul și, în plus, subclasele din alte pachete.

Comenzi înrudite

  • Clase și obiecte (class): O clasă (cuvântul cheie class) descrie un tip nou: câmpuri pentru date și metode pentru comportament; obiectele sunt instanțele ei.
  • Pachete și importuri (package, import): package așază clasa într-un pachet (un spațiu de nume, ca un director); import permite folosirea claselor din alte pachete după numele scurt.
  • static: static leagă un câmp sau o metodă de clasă, nu de un obiect: există o singură copie, accesată prin numele clasei.
  • final (și static final): final interzice schimbarea: o variabilă primește valoare o singură dată, o metodă nu poate fi rescrisă, o clasă nu poate fi extinsă.
  • Module (module-info.java): Un modul (module-info.java) grupează pachete și declară explicit de ce module depinde (requires) și ce pachete oferă altora (exports).