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:
| Belirleyici | Aynı sınıf | Aynı paket | Alt 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
privateyap; gerekiyorsa metotlarla aç. - Yalnızca dış dünyanın kullanması gereken metotları
publicyap. - İç yardımcı metotları
privatetut. 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ılabilir1// 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}Ornek2
çalıştırılabilir1// 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}