Eğitim Portalı/Java/Erişim Belirleyiciler (Access Modifiers)
Java01-java/34-erisim-belirleyiciler

Erişim Belirleyiciler (Access Modifiers)

Nesne yönelimli tasarımın kalbinde kapsülleme (encapsulation) yatar: bir sınıfın iç ayrıntılarını gizleyip dışarıya yalnızca güvenli, kontrollü bir arayüz sunmak. Bunu sağlayan araç erişim belirleyicileridir. Her alan…

Erişim Belirleyiciler (Access Modifiers)

Nesne yönelimli tasarımın kalbinde kapsülleme (encapsulation) yatar: bir sınıfın iç ayrıntılarını gizleyip dışarıya yalnızca güvenli, kontrollü bir arayüz sunmak. Bunu sağlayan araç erişim belirleyicileridir. Her alan, metot ve sınıf için "buna nereden erişilebilir?" sorusunu yanıtlarlar. Doğru erişim belirleyicisini seçmek, kodunu hem güvenli hem de sürdürülebilir kılar.

Dört erişim düzeyi

Java'da dört erişim düzeyi vardır; en genişten en dara:

BelirleyiciAynı sınıfAynı paketAlt sınıf (farklı paket)Her yer
public
protected
(default) paket-özel
private
  • public: Her yerden erişilir. Sınıfın dış dünyaya sunduğu API (genelde metotlar).
  • protected: Aynı paket + (farklı paketteki) alt sınıflar. Kalıtım için açılan üyeler.
  • default (belirleyici yazılmazsa): Yalnızca aynı paket. "Paket-özel" (package-private).
  • private: Yalnızca tanımlandığı sınıf. İç ayrıntılar, durum (state), yardımcı metotlar.

Not: Bu portalın örnekleri tek dosyada (default pakette) çalışır; bu yüzden default ve protected, farklı paket davranışını birebir gösteremez. Tablodaki "farklı paket" davranışını akılda tut; örnekler aynı-paket ve kalıtım senaryolarını gösterir.

private: kapsüllemenin temeli

Bir nesnenin durumunu (alanlarını) private yapıp dışarıya yalnızca metotlarla (getter/setter veya iş metotları) açmak, nesnenin her zaman geçerli kalmasını sağlar:

class Hesap {
    private double bakiye;                 // dışarıdan doğrudan değiştirilemez
    public double getBakiye() { return bakiye; }
    public void paraYatir(double t) { if (t > 0) bakiye += t; } // kural burada
}

Böylece kimse hesap.bakiye = -100 yapamaz; tüm değişiklikler kuralları uygulayan metotlardan geçer. Örnek 1 (./Ornek1.java) dört düzeyi bir hesap sınıfında gösterir: public her yerden, default/protected aynı paketten erişilir, private yalnızca sınıf içinden.

protected ve kalıtım

protected, "dış dünyaya kapalı ama alt sınıflara açık" demektir. Bir üst sınıfın, alt sınıfların kullanmasını istediği ama dışarıya açmak istemediği üyeler için idealdir:

class Calisan { protected double tabanMaas; private String sicilNo; }
class Yonetici extends Calisan {
    double toplam() { return tabanMaas + prim; } // protected'a erişir
    // sicilNo'ya ERİŞEMEZ (private)
}

Örnek 2 (./Ornek2.java) bir Yonetici'nin üst sınıftaki protected alanlara erişip private alana erişemediğini gösterir.

Sınıf düzeyinde erişim

Top-level (en dış) sınıflar yalnızca public veya default olabilir (private/protected olamaz). Bir dosyada en fazla bir public top-level sınıf olabilir ve adı dosya adıyla eşleşmelidir. İç (nested) sınıflar ise dört düzeyin hepsini kullanabilir.

İyi uygulama: en dar erişimi seç

Altın kural: gereken en dar erişim düzeyini kullan.

  • Alanları varsayılan olarak private yap; gerekiyorsa metotlarla aç.
  • Yalnızca dış dünyanın kullanması gereken metotları public yap.
  • İç yardımcı metotları private tut.
  • protected'i bilinçli kullan (kalıtım sözleşmesinin parçası olur).

Bu yaklaşım "bilgi gizleme" (information hiding) ilkesidir: ne kadar az şey açığa çıkarsa, sınıfı o kadar rahat değiştirebilirsin (dış kod etkilenmeden).

Özet

Dört erişim düzeyini (public/protected/default/private) ve hangisinin nereden erişilebilir olduğunu; private ile kapsüllemeyi (Örnek 1) ve protected ile kalıtım arasındaki ilişkiyi (Örnek 2) öğrendik. "En dar erişimi seç" ilkesi, sağlam ve sürdürülebilir tasarımın temelidir. Sırada, sınıfları düzenlemenin ve isim çakışmalarını önlemenin yolu: paketler.

Kod Örnekleri(2)

Ornek1

çalıştırılabilir
Ornek1.java
1// Ornek1: Erişim belirleyiciler — public, protected, default (paket), private.
2// Bir üyeye NEREDEN erişilebileceğini belirler. (Aynı dosyadaki sınıflar aynı pakettedir.)
3// Çalıştırma: java Ornek1.java
4public class Ornek1 {
5
6    public static void main(String[] args) {
7        Hesap h = new Hesap("Ada", 1000);
8
9        // public: her yerden erişilebilir
10        System.out.println("public sahip       : " + h.sahip);
11
12        // default (paket-özel) ve protected: AYNI paketteyiz, erişilebilir
13        System.out.println("default sube        : " + h.sube);
14        System.out.println("protected subeKodu  : " + h.subeKodu);
15
16        // private: SADECE Hesap sınıfının içinden erişilebilir; buradan ERİŞİLEMEZ.
17        // System.out.println(h.bakiye);  // <-- derlenmez: bakiye has private access
18
19        // private alana yalnızca sınıfın kendi metotları (public arayüz) üzerinden erişilir.
20        System.out.println("private bakiye (getter ile): " + h.getBakiye());
21        h.paraYatir(250);
22        System.out.println("Yeni bakiye: " + h.getBakiye());
23    }
24}
25
26class Hesap {
27    public String sahip;       // her yerden
28    String sube = "Merkez";    // default: yalnızca aynı paketten
29    protected String subeKodu = "0001"; // aynı paket + alt sınıflar
30    private double bakiye;      // yalnızca bu sınıf
31
32    public Hesap(String sahip, double bakiye) {
33        this.sahip = sahip;
34        this.bakiye = bakiye;
35    }
36
37    // private alanı dışarıya kontrollü açan public metotlar (kapsülleme).
38    public double getBakiye() { return bakiye; }
39    public void paraYatir(double tutar) {
40        if (tutar > 0) bakiye += tutar;
41    }
42
43    // private yardımcı metot: yalnızca sınıf içi kullanım.
44    private boolean gecerliMi(double tutar) { return tutar > 0; }
45}
Çıktı yerel JDK 21 ile yakalandı — tarayıcıda JVM çalışmaz.

Ornek2

çalıştırılabilir
Ornek2.java
1// Ornek2: protected ve kalıtım — alt sınıf protected üyelere erişir, private'a erişemez.
2// Çalıştırma: java Ornek2.java
3public class Ornek2 {
4    public static void main(String[] args) {
5        Yonetici y = new Yonetici("Burak", 30000, 15000);
6        y.bilgiYaz();
7        System.out.println("Toplam maaş: " + y.toplamMaas());
8    }
9}
10
11class Calisan {
12    protected String ad;        // alt sınıflar erişebilir
13    protected double tabanMaas; // alt sınıflar erişebilir
14    private String sicilNo = "GIZLI"; // alt sınıf bile erişemez
15
16    public Calisan(String ad, double tabanMaas) {
17        this.ad = ad;
18        this.tabanMaas = tabanMaas;
19    }
20
21    // private alana erişim yalnızca bu sınıftan; alt sınıfa kontrollü açmak için protected/public metot.
22    protected String maskeliSicil() { return "****" ; }
23}
24
25class Yonetici extends Calisan {
26    private double prim;
27
28    public Yonetici(String ad, double tabanMaas, double prim) {
29        super(ad, tabanMaas);
30        this.prim = prim;
31    }
32
33    double toplamMaas() {
34        // protected alanlara DOĞRUDAN erişebiliriz (kalıtım).
35        return tabanMaas + prim;
36    }
37
38    void bilgiYaz() {
39        // ad, tabanMaas -> protected (erişilir); sicilNo -> private (ERİŞİLEMEZ).
40        System.out.println(ad + " | taban: " + tabanMaas + " | sicil: " + maskeliSicil());
41        // System.out.println(sicilNo); // <-- derlenmez: sicilNo private
42    }
43}
Çıktı yerel JDK 21 ile yakalandı — tarayıcıda JVM çalışmaz.