Kodunuza Kimler Dokunabilir
Bir erişim belirleyici, bir sınıfın, alanın, metodun veya yapıcının önünde yer alan ve onu başka kimin kullanmasına izin verildiğine karar veren bir anahtar kelimedir. Kapsüllemenin temelidir: bir sınıfın karmakarışık iç yapısını gizler ve yalnızca başka kodun çağırmasına güvendiğiniz kısımları dışa açarsınız.
Java'nın en açıktan en kapalıya doğru dört seviyesi vardır: public, protected, default (hiç anahtar kelime yok) ve private. Bunları doğru yaparsanız bir sınıf daha sonra değiştirilebilir hale gelir; çünkü dışarıdaki hiçbir şey, korumaya hiç söz vermediğiniz ayrıntılara bağlı kalmaz.
private: Yalnızca Sınıfın İçinde Görünür
private en sıkı seviyedir. Bir private üyeye yalnızca aynı sınıfın içinde yazılmış kod dokunabilir - alt sınıflar değil, aynı paketteki diğer sınıflar değil, hiç kimse. Alanlarınızın çoğunun yeri burasıdır.
balance alanı private'tır, bu yüzden onu değiştirmenin tek yolu, negatif tutarları reddeden deposit aracılığıyladır. Eğer balance public olsaydı, herhangi bir kod account.balance = -9999 yazıp kontrolü tamamen atlayabilirdi. O koruma, alanı gizlemenin tüm amacıdır.
main içindeki account.balance = 500; satırının yorumunu kaldırmayı deneyin; bir derleme hatası alırsınız: balance has private access in BankAccount.
public: Her Yerde Görünür
public tam zıt uçtur - herhangi bir yerdeki herhangi biri üyeyi kullanabilir. Başka kodun çağırması amaçlanan metot adlarınız genellikle public'tir. Başka paketlerden erişilebilir olması gerektiğinde sınıfın kendisi de öyledir.
Yaygın kalıp - bazen bir sınıfın genel API'si olarak adlandırılır - şudur: private alanlar, public metotlar. Alanlar, başka kimsenin dokunmaması gereken durumu tutar; metotlar ise giriş ve çıkışın denetlenen kapılarıdır. Yukarıdaki getBalance ve deposit tam olarak budur.
default (Package-Private): Hiç Anahtar Kelime Yok
Hiçbir belirleyici yazmazsanız default erişim elde edersiniz, buna package-private da denir. Üye, aynı paketteki her sınıfa görünür ve dışındaki her şeye görünmezdir. Bu seviye için bir anahtar kelime yoktur - bir anahtar kelimenin yokluğu bizzat seviyenin kendisidir.
class Invoice { // belirleyici yok -> yalnızca bu paketin içinde görünür
int amount; // belirleyici yok -> package-private alan
}
Bu, pek çok yeni başlayanı yakalar: public'i atlamak bir şeyi private yapmaz, package-private yapar. Gizli tutmayı düşündüğünüz bir alan, aynı pakette bulunan herhangi bir sınıf tarafından hâlâ tamamen okunabilir ve yazılabilirdir. Gerçekten gizli olmasını istiyorsanız private'ı açıkça yazmanız gerekir.
Default erişim, bir paketin uygulama ayrıntısı olan yardımcı sınıflar için gerçekten kullanışlıdır - onları dışa aktarmazsınız, ama paket içinde iş birliği yapan sınıflar onları serbestçe kullanabilir.
protected: Paket Artı Alt Sınıflar
protected, default'tan bir kademe daha gevşektir. Bir protected üye, default'ın görünür olduğu her yerde (aynı paket) görünürdür ve ayrıca alt sınıflara da - farklı bir paketteki alt sınıflara bile. Sizinkini genişleten sınıflarla paylaşmak istediğiniz ama tüm dünyayla değil, şeyler için tasarlanmıştır.
Dog, name ve sound()'a erişir çünkü bunlar protected'tir ve Dog bir alt sınıftır. Alt sınıf olmayan ve pakette bulunmayan dışarıdaki kod hâlâ onlara dokunamaz. Genişletilmek üzere tasarlanan bir sınıf yaparken protected'e başvurun; aksi halde private'ı tercih edin.
Dört Seviye Bir Bakışta
İşte en kısıtlayıcıdan en açığa, tüm tablo:
| Belirleyici | Aynı sınıf | Aynı paket | Alt sınıf (başka paket) | Her yer |
|---|---|---|---|---|
private | evet | hayır | hayır | hayır |
| default | evet | evet | hayır | hayır |
protected | evet | evet | evet | hayır |
public | evet | evet | evet | evet |
Basit bir genel kural: private ile başlayın ve yalnızca bir şey gerçekten daha geniş erişime ihtiyaç duyduğunda gevşetin. Erişimi daha sonra genişletmek, başka kod bir üyeye bağımlı hale geldikten sonra onu daraltmaktan çok daha kolaydır.
Sınıfların Kendisindeki Belirleyiciler
Erişim belirleyiciler yalnızca üyelere değil, sınıflara da uygulanır - ancak üst düzey bir sınıf (başka bir sınıfın içinde iç içe olmayan) yalnızca public veya default olabilir. Üst düzey bir private veya protected sınıf yazamazsınız.
public class Order { ... } // herhangi bir paketten erişilebilir
class LineItem { ... } // default - yalnızca bu paket görebilir
Bir public üst düzey sınıf, kendi adıyla adlandırılmış bir dosyada bulunmalıdır (Order.java). İç içe sınıflar ise dört belirleyicinin tümünü kullanabilir - yukarıdaki örneklerin iç sınıfları private veya default olarak işaretleyebilmesinin nedeni de budur. İnce bir nokta: package-private bir tür döndüren bir public metot, dışarıdaki çağıranlar için pek kullanışlı değildir, bu yüzden public yüzeyinizi tutarlı tutun.
Sıradaki: Statik Üyeler
Şimdiye kadar buradaki her alan ve metot bir örneğe aittir - new ile bir nesne oluşturursunuz ve sonra üzerinde metotlar çağırırsınız. Ama bazen bir değer ya da davranış, her örnek arasında paylaşılan, sınıfın bütününe aittir - örneğin kaç nesne bulunduğunu sayan bir sayaç gibi. İşte static anahtar kelimesi bunun içindir ve sırada o var.
Sıkça Sorulan Sorular
Java'daki dört erişim belirleyici nedir?
public, private, protected ve default (anahtar kelimesiz, package-private olarak da bilinir). public her yerde görünürdür, private yalnızca aynı sınıfın içinde, protected paketin içinde artı alt sınıflarda, default ise yalnızca aynı paketin içinde görünürdür.
Java'da public ile private arasındaki fark nedir?
public, herhangi bir yerdeki herhangi bir kodun üyeye erişebileceği anlamına gelir. private ise yalnızca aynı sınıftaki kodun erişebileceği anlamına gelir - alt sınıflar ve diğer sınıflar onu göremez bile. Genellikle alanları private yapar ve onları public metotlar aracılığıyla dışa açarsınız.
Bir Java alanının erişim belirleyicisi olmaması ne anlama gelir?
Anahtar kelime olmaması default (package-private) erişim anlamına gelir: üye, aynı paketteki her sınıfa görünür ama dışında görünmezdir. public'ten daha katı, private'tan daha gevşektir - ve yanlışlıkla yazmamak kolaydır, bu yüzden bu konuda bilinçli olun.