Zapouzdření a viditelnost členů třídy

Proč to potřebuji?

Zapouzdření chrání vnitřní stav objektu před neoprávněným přístupem a umožňuje validaci dat. Bez něj hrozí neplatné stavy objektů a obtížný refaktoring.

Teorie

Zapouzdření (encapsulation) = skrytí vnitřní implementace a poskytnutí kontrolovaného přístupu přes veřejné metody. Atributy jsou private, přístup přes gettery/settery.

Důsledky nedodržení: přímý přístup k atributům umožňuje nastavit neplatné hodnoty, ztěžuje refaktoring (změna implementace rozbije všechen kód, který přistupuje přímo) a znemožňuje validaci.

Příklady

// === ŠPATNĚ – bez zapouzdření ===
public class UcetSpatne {
    public double zustatek;  // veřejný atribut
    public String majitel;
}

// Problém: kdokoli může nastavit nesmyslné hodnoty
UcetSpatne u = new UcetSpatne();
u.zustatek = -999999;  // žádná kontrola!
u.majitel = "";         // prázdný řetězec

// === SPRÁVNĚ – se zapouzdřením ===
public class Ucet {
    private double zustatek;
    private String majitel;

    public Ucet(String majitel, double pocatecniVklad) {
        setMajitel(majitel);
        this.zustatek = pocatecniVklad;
    }

    public double getZustatek() {
        return zustatek;  // pouze čtení
    }

    // Žádný setZustatek() – zůstatek se mění jen přes operace
    public void vloz(double castka) {
        if (castka <= 0) throw new IllegalArgumentException("Musí být kladná");
        zustatek += castka;
    }

    public void vyber(double castka) {
        if (castka <= 0) throw new IllegalArgumentException("Musí být kladná");
        if (castka > zustatek) throw new IllegalStateException("Nedostatek");
        zustatek -= castka;
    }

    public String getMajitel() { return majitel; }

    public void setMajitel(String majitel) {
        if (majitel == null || majitel.isBlank()) {
            throw new IllegalArgumentException("Majitel nesmí být prázdný");
        }
        this.majitel = majitel;
    }
}

// Výhody:
// 1. Validace v setteru – nelze nastavit neplatné hodnoty
// 2. Read-only vlastnosti (bez setteru) – zustatek
// 3. Změna implementace neovlivní volající kód
// 4. Lze přidat logiku (logování, notifikace) do getterů/setterů

Shrnutí

Klíčové body

  • Atributy vždy private, přístup přes getter/setter
  • Setter = validace, getter = kontrolovaný přístup
  • Bez zapouzdření: neplatné stavy, těžký refaktoring, žádná kontrola
  • Read-only vlastnost = getter bez setteru