Erişim Düzenleyiciler

Getter ve setter konumuzdan sonra, javadaki başka bir önemli kavrama da değinmek istiyorum. Kod bloklarımızda sıklıkla gördüğümüz public anahtar sözcüğünün ne işe yaradığını, bu sözcüğün alternatiflerini ve bütün bu alternatiflerin ne anlama geldiğini bu yazıda ele alacağız.

Öncelikle encapsulation kavramına değinmek gerekiyor. Zira bir önceki konumuzda bazı eksiklerimiz olduğunu söylemiştik. Encapsulation, yani sarmalama, nesneye yönelik programlamanın en temel kavramlarındandır. Bu kavramı, temel olarak bilginin uygun şekilde saklanması olarak düşünebiliriz. Peki ama neden bir bilgiyi saklamak isteyelim ki? Bunun sebebine aslında getter ve setter methodlarımızda değinmiştik. Ancak bu yazıda farklı bir örnekle temsil etmek istiyorum.

Bir markete gittiğimizi düşünelim. Aldıklarımızı kasaya getirdiğimizde kasiyer bunların barkodunu okutur ve sistem otomatik olarak fiyatları size gösterir. Ancak müşteri olarak bizim fiyatlara müdahale yetkimiz yoktur. Yani 100 TL’lik ürünün fiyatını müşteri olarak 50 TL olarak değiştiremeyiz. Ancak bunu marketin personeli değiştirebilir. Belki her personel bu yetkiye sahip olmayabilir. Görüldüğü üzere bazen bir değeri setlemek çeşitli ayrıcalıklara sahip olmayı gerektiriyor. Aynı durum 100 TL’lik ürünün markete geliş fiyatını görmek istediğimizde de geçerli olacaktır. Yani bazı değerleri getlemek için ayrıcalık sahibi olmalısınız.

Bu durumu önceki yazımızdaki örnek üzerinden tekrar değerlendirirsek; bir ApartmanDairesi nesnesinin fieldlarına getter veya setter kullanmadan ulaşılamaz olmalıdır. Ancak önceki örneğimizin main methodunu hatırlarsak, hem getter/setter kullanılan insaat2() hem de kullanılmayan insaat() methodları çalışmaktaydı. Oysa biz insaat2() methodunu fieldların denetimini sağlamak için yazmıştık. İşte bu denetimi zorunlu kılmanın bir yolu var: Doğru erişim düzenliyici kullanmak!

Bu yazımız için 03 – AccessModifiers isminde bir proje oluşturalım. Bu defa öncelikle TestClass sınıfımızı oluşturacağım. Bu bilgi bundan sonraki tüm projelerimizde de geçerli olacaktır. Bununla birlikte, market örneğinden yola çıkarak bir sınıf kodlayalım. Bu sınıf üzerinde fiyat ve isim tutan bir ürünü temsil etsin ve ismi de Urun olsun.

public class Urun {

	public int fiyat;
	
	public String isim;
	
}

Main methodumuzun içerisinde bu sınıfı kullanarak bir nesne yaratalım. Temsili olarak bir sakızı düşünebiliriz. İsmi sakiz ve tipi/sınıfı Urun olan bir değişken yaratalım. sakiz’in fiyat değeri 1 ve isim değeri de çiklet olsun. Nihayetinde bu objenin fiyat ve ismini konsola yazdıralım.

public class TestClass {

	public static void main(String[] args) {

		Urun sakiz = new Urun();
		sakiz.fiyat = 1;
		sakiz.isim = "çiklet";
		
		System.out.println(sakiz.fiyat);
		System.out.println(sakiz.isim);
	}
	
}

Yukarıdaki örnekte görüldüğü üzere, sakiz nesnesinin fiyatını direkt olarak değiştirebiliyoruz. Aynı şekilde fieldların değerini hiçbir denetime tabi olmadan okuyabiliyoruz. Şimdi bir düzenleme daha yapıyoruz ve Urun sınıfımızdaki getter ve setterları ekliyoruz.

public class Urun {

	private int fiyat;
	
	public String isim;

	public int getFiyat() {
		return fiyat;
	}

	public void setFiyat(int fiyat) {
		this.fiyat = fiyat;
	}

	public String getIsim() {
		return isim;
	}

	public void setIsim(String isim) {
		this.isim = isim;
	}
	
}

Yukarıdaki kodu dikkatli incelerseniz bir durumun farkına varacaksınız. Getter ver setterları ürettikten sonra bir düzenleme daha yaptım ve fiyat fieldının önündeki public anahtar sözcüğünü private ile değiştirdim. Bu değişikliği siz de sağladığınızda editörünüzde bir hata aldığınızı göreceksiniz.

Buradaki hatayı incelerseniz (imleci kırmızı çizili yere getirir veya ampül işaretine tıklarsanız) fiyat alanının görünü olmadığına dair bir uyarı göreceksiniz. Bu durumu aşmak için fiyatı set ettiğim yerde setter ve get ettiğim yerde getter kullanmalıyız. Kodumuzu aşağıdaki gibi düzenliyoruz.

public class TestClass {

	public static void main(String[] args) {

		Urun sakiz = new Urun();
		sakiz.setFiyat(1);
		sakiz.isim = "çiklet";
		
		System.out.println(sakiz.getFiyat());
		System.out.println(sakiz.isim);
	}
	
}

Bu değişikliği yaptığımızda getter ve setter kullanımını zorunlu hale getirmiş olduk. Peki tam olarak neler oldu? Bizim burada yaptığımız şey bir fieldın erişim seviyesini değiştirmek oldu. Javada bunu yaparken fieldların, methodların ve hatta sınıfların tanımlarının önünde kullanabileceğimiz, 4 adet erişim düzenleyicisi bulunmaktadır.

public : Erişimin her yerden sağlanabildiğini gösterir. Diğer sınıflar, diğer paketler bu erişim düzenliyicisi ile tanımlanmış methodlarınıza, fieldlarınıza ve sınıflarınıza ulaşabilir. Güvende kalmak için uygulama düzeyinde gerekmedikçe public sözcüğünü kullanmamalıyız.

protected : Önüne geldiği varlığı, bulunduğu paket, alt sınıflar ve sınıfın kendi içinden çağrılabilir halde tanımlamak için kullanılır. Buradaki alt sınıf ve paket kavramı kafanızı kurcalamasın. Bunların bir kısmına ilerleyen dönemde değineceğiz.

boş erişim düzenleyici : Diğer 3 erişim düzenleyiciyi kullanmadan tanım yapmak anlamını taşır. Mesela Urun sınıfımızdaki isim fieldının önündeki public sözcüğünü silersek boş erişim düzenliyicisi ile bu alanı tanımlamış oluruz. Boş erişim düzenleyicisi kullandığınız varlıklar alt sınıflardan ve diğer sınıflardan direkt olarak çağırılamaz. Ancak paket içerisinden erişilebilir durumdadır.

private : En sıkı erişim düzenleyicisidir. Önüne konulduğu java elemanını sadece o sınıf içerisinden erişilebilir hale getirir. Bu erişim düzenleyicisi parmağa bağlanan bir ip gibi aklınızda olmalı, bütün varlıklarınızı öncelikle private tanımlamayı düşünmelisiniz.

sınıfpaketalt sınıfdiğer sınıflar
publicVarVarVarVar
protectedVarVarVarYok
boşVarVarYokYok
privateVarYokYokYok
Erişim Tablosu

Örneğimize dönecek olursak; fiyat alanını private yapmamız sebebiyle alana direkt erişim yetkisi sadece sınıfın kendisinde kalmış durumda. Dolayısı ile farklı bir sınıftan (TestClass) buraya erişim sağlanamıyor. Ancak bu alanın setter ve getterları public olduğundan ve biz bunlara ulaşabildiğimizden, dolaylı olarak fiyat bilgisine erişebilmekteyiz. Yani fiyat bilgisine erişim denetim altına alınmış durumda. Ancak isim bilgisi için aynı şey geçerli değil. İsim public olarak tanımlanmış bir field olduğundan direkt erişim mümkün ve değeri değiştirilebilir ve bir denetime tabi olmadan okunabilir durumda.

Bu noktada artık farklı önlemler alabilir durumdayız. Diyelim ki fiyat girişi yapan personel kazara fiyatı 0 girdi. Setter methodumuz içerisinde gelen bu fiyatın kontrolünü yapabilir durumda olduğumuzdan; “Eğer fiyat sıfır girildiyse hata ver” ya da “İsmi olmayan ürünün adını ‘Tanımsız’ olarak listele” gibi daha programatik kontrolleri sağlayabilir halde oluruz.

Son iki yazımızla birlikte encapsulation konusuna değinmiş olduk. Özetle encapsulation sayesinde alanlarımızı sadece-okuma (read-only), sadece yazma (write-only) gibi biçimlerde kullanmamız mümkündür. Ayrıca veri okumayı ve yazmayı daha kontrollü bir hale getirir. Uygulamanızı daha güvenli kılar ve bakım süreçlerini kolaylaştırır. Hata ayıklama süreçlerinde işimizi kolaylaştırır. Kodumuzun yeniden kullanılabilir olmasını sağlar. İlerleyen yazılarla birlikte bunların hepsini yavaş yavaş bir arada kullanabilmeye başlayacağız. Kendinize bir ödev olarak önceki projeleri getter ve setterlı halde yazmayı alabilirsiniz. Pratik sizi daha iyi bir noktaya taşıyacaktır. Bir sonraki yazıda görüşmek üzere.

Leave a Comment

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir