Getter ve Setter

Son yazımızda KaraAraclari sınıfımızda bulunan bazı methodların kullanımını ve bunların birbiri ile ilişki içerisinde nasıl hareket edebileceğini görmüştük. Sınıf yapılarına dair yazılarımızın genelinde ayrıca constructor kullanımına da odaklanmıştık.

Bu yazımızda yine sınıf yapılarının bir parçası olarak kabul edilen, getter ve setter ismi verilen methodlardan bahsedeceğiz. İsimlerinden yola çıkarak bu methodların bazı değerleri getirdiğini (getter) ve bazı değerleri güncellediğini (setter) söyleyebiliriz. Yazılım dünyasında bu methodların yaptığı işlere “get etmek” ve “set etmek” ismi verilmektedir.

Bildiğiniz gibi sınıfların ana yapılarından bir tanesi, o sınıfta bulunan fieldlardır. Daha evvel yazdığımız sınıfımızda iki adet fieldımız vardı. Kısaca bunları hatırlamak gerekirse aşağıdaki kod parçasına göz atabilirsiniz.

	public int koltukSayisi;
	
	public String renk;

Sürekli aynı proje üzerinden devam etmemek için, gelin bu yazımız için yeni bir proje oluşturalım. Bu yazımızda ele alacağımız projemizin ismini 02 – GettersAndSetters olarak belirleyelim. Editörümüzün sol tarafındaki kısma baktığımızda şöyle bir görüntüyle karşılaşacağız.

Getter ve setter örneğimiz için, yeni bir sınıf daha yaratmamız gerekiyor. Bu tarz durumlarda, çok klişe olarak 4 işlemden sorumlu bir sınıf yazılır. Ben mümkün olduğunca bundan uzak durmak istiyorum. Java sınıflarını gerçek hayattaki objelere benzetmek, OOP mantığını güçlendirecek bir hareket olacaktır. Eğer OOP konusunda kendinizi yeterli hissetmiyorsanız önce elle tutulabilir örnekleri düşünmeniz yararlı olacaktır. Matematik işlemleri, soyut kalmaları sebebiyle, bu anlattığım duruma uymamakta. Dolayısı ile biz farklı bir örnek ile ilerleyeceğiz.

Gelin bugün bir inşaat işi üzerine düşünelim. Diyelim ki bir apartman inşa edilecek. Bu apartmandan daire almak isteyen farklı profilde insanlar var. Dolayısı ile farklı dairelere ihtiyacımız var. Her bir daireyi bu işin içerisindeki bir nesne olarak düşünebiliriz. Bir apartman dairesi denildiğinde aklımıza gelen şeyleri düşünelim. Bir kapıdan içeri gireriz, duvarları boyalı, odaları sayılı olan, belki iki katlı olan, bazen açık mutfaklı olan bir yapıdır. Buradaki özellikleri düşündüğümüzde çok fazla madde çıkabilir durumdadır. Gelin bunların kısıtlı bir kısmına odaklanalım. Projemizde ApartmanDairesi isminde bir sınıf yaratıp bu örnek için kullanmaya başlayalım. Bizim apartman dairemizi bir duvar rengi, oda sayısı ve çelik kapılı olup olmaması temsilediyor olsun.

public class ApartmanDairesi {

	public String duvarRengi;
	
	public int odaSayisi;
	
	public boolean celikKapiliMi;
	
}

Uygulamamız, inşaata söz konusu olan her bir apartmanın java nesnesini yaratacak olsun. Yani apartmanımızdaki farklı farklı daireleri yukarıdaki sınıf ile oluşturacağız. Bu işi de önceki örneğimizde olduğu gibi TestClass isminde, main methodunu barındıran bir sınıf ile yapacağız. 4 adet daire oluşturuyor ve bunların fieldlarını dolduruyoruz.

public class TestClass {

	public static void main(String[] args) {
		
		ApartmanDairesi daire1 = new ApartmanDairesi();
		daire1.celikKapiliMi = true;
		daire1.duvarRengi = "Mavi";
		daire1.odaSayisi = 3;
		
		ApartmanDairesi daire2 = new ApartmanDairesi();
		daire2.celikKapiliMi = false;
		daire2.duvarRengi = "Gri";
		daire2.odaSayisi = 3;
		
		ApartmanDairesi daire3 = new ApartmanDairesi();
		daire3.celikKapiliMi = true;
		daire3.duvarRengi = "Mavi";
		daire3.odaSayisi = 2;
		
		ApartmanDairesi daire4 = new ApartmanDairesi();
		daire4.celikKapiliMi = true;
		daire4.duvarRengi = "Yeşil";
		daire4.odaSayisi = 1;
		
	}
}

Main methodumuzu çalıştırdığımızda 4 adet nesne oluşturmuş olacağız. Bunlar gerçek dünya gözüyle bakıldığında birbirinden farklı özelliklere sahip 4 adet apartman dairesidir. Java diliyle konuşursak; ApartmanDairesi sınıfına ait 4 farklı instance/nesne yaratmış durumdayız.

Varsayalım ki inşaat bitti ve dairelere taşınmalar başladı. Ancak daire2‘nin sahibi eski kararından pişman oldu ve çelik kapı taktırmak istedi. Bu durumda programatik olarak yapmamız gereken daire2 nesnesine ait celikKapiliMi fieldını true olarak güncellemektir. Gerçek hayatta yapılacak şey ise kapının sökülüp yenisinin takılmasıdır.

daire2.celikKapiliMi = true;

Bu defa tersten düşünelim. 3 odalı bir eviniz var ve bunu 4 odalı yapmak istiyorsunuz. Bir odanızı ikiye bölmediğinizi düşünürsek 4. bir odayı inşa etmeniz söz konusu olamamaktadır. Ancak programatik olarak 3 odalı olan daire1 nesnemize bunu yapabilmemizin önünde bir engel yoktur. Kısacası aşağıdaki kodu main methodumuza yazdığımızda çalıştığını görürüz.

daire1.odaSayisi = 4;

Demek ki java dünyasında, tıpkı gerçek hayatta olduğu gibi, bazı aksiyonları denetleme ihtiyacı duymaktayız. Yani duvarları boyamak bir ustanın varlığına, eve oda eklemek bazı fiziksel engellere tabidir. Şu ana kadar bir değeri setlemek üzerine konuştuk. Bazı durumlarda ise getlerken denetime ihtiyaç duyabiliriz. Örneğin daire sahipleri evinin rengini paylaşmak istemiyor olabilir. Bu durumda aşağıdaki kodun çıktı vermemesini sağlamak isteriz.

System.out.println(daire1.duvarRengi);

Bütün bu durumları kontrol altında tutmak için field değerlerinin okunması ve yazılması esnasında yardımcı methodlar kullanabiliriz. Bunlara getter ve setter methodlar ismi verilmektedir. ApartmanDairesi sınıfımızın fieldları için getter ve setter methodları oluşturalım. Sınıfımızı aşağıdaki gibi düzenliyoruz.

public class ApartmanDairesi {

	public String duvarRengi;
	
	public int odaSayisi;
	
	public boolean celikKapiliMi;

	public String getDuvarRengi() {
		return duvarRengi;
	}

	public void setDuvarRengi(String duvarRengi) {
		this.duvarRengi = duvarRengi;
	}

	public int getOdaSayisi() {
		return odaSayisi;
	}

	public void setOdaSayisi(int odaSayisi) {
		this.odaSayisi = odaSayisi;
	}

	public boolean isCelikKapiliMi() {
		return celikKapiliMi;
	}

	public void setCelikKapiliMi(boolean celikKapiliMi) {
		this.celikKapiliMi = celikKapiliMi;
	}
	
}

Dikkat edilirse getter methodlar (ismi get ile başlayan) geriye o fieldın tipinde dönüş sağlarken, setter methodlar geriye değer dönmüyor. Getter ve setter methodların olağan davranışı bu şekildedir. Tekrar koda dikkat ederseniz, setter methodlar parametre alırken, getter methodlar almamaktadır. Gerçek hayatta da, evinizin duvar rengini görmek için ek bir parametreye ihtiyaç duymazsınız. Ancak evinizin duvarını boyamak için hangi renk boyayı istediğinizi belirtmek durumundasınızdır. Yani bir değeri setliyorsam yeni değeri belirtirim. Ancak bir değeri getliyorsam değer zaten oradadır ve parametre vermem.

Bu noktada bir de kısayoldan bahsetmek istiyorum. Çoğu editör, getter ve setter üretimi için kısayollar barındırmaktadır. Eclipse ile getter ve setter üretmek için sınıfınızın içerisinde boş bir yerde sağ tıklayın. Açılan menüde source kısmına gelip Generate Getters and Setters menüsüne tıklayınız.

Açılan pencerede getter ve setter üretmek istediğiniz tüm fieldları işaretleyip, Generate butonuna tıklarsanız, editör tüm getter ve setterları sizin için sınıfınızın içerisine ekleyecektir.

Getter ve setterları ekledikten sonra test sınıfımızı da değiştiriyoruz. Field değerlerine direkt ulaşım yerine getter ve setterları kullanacağız. Programımızı uygun şekilde değiştireceğiz. Ancak karşılaştırma yapmayı kolaylaştırmak için Programın ilk halinde bulunan akışı insaat() isminde bir methoda alacağım. insaat2() ismindeki methodda ise getter setter kullanımını göstereceğim. Test sınıfımızı aşağıdaki gibi değiştiriyoruz.

public class TestClass {

	public static void main(String[] args) {
		
		insaat();
		insaat2();
		
	}

	private static void insaat2() {
		
		ApartmanDairesi daire1 = new ApartmanDairesi();
		daire1.setCelikKapiliMi(true);
		daire1.setDuvarRengi("Mavi");
		daire1.setOdaSayisi(3);
		
		ApartmanDairesi daire2 = new ApartmanDairesi();
		daire2.setCelikKapiliMi(false);
		daire2.setDuvarRengi("Gri");
		daire2.setOdaSayisi(3);
		
		ApartmanDairesi daire3 = new ApartmanDairesi();
		daire3.setCelikKapiliMi(true);
		daire3.setDuvarRengi("Mavi");
		daire3.setOdaSayisi(2);
		
		ApartmanDairesi daire4 = new ApartmanDairesi();
		daire4.setCelikKapiliMi(true);
		daire4.setDuvarRengi("Yeşil");
		daire4.setOdaSayisi(1);
		
	}

	private static void insaat() {
		
		ApartmanDairesi daire1 = new ApartmanDairesi();
		daire1.celikKapiliMi = true;
		daire1.duvarRengi = "Mavi";
		daire1.odaSayisi = 3;
		
		ApartmanDairesi daire2 = new ApartmanDairesi();
		daire2.celikKapiliMi = false;
		daire2.duvarRengi = "Gri";
		daire2.odaSayisi = 3;
		
		ApartmanDairesi daire3 = new ApartmanDairesi();
		daire3.celikKapiliMi = true;
		daire3.duvarRengi = "Mavi";
		daire3.odaSayisi = 2;
		
		ApartmanDairesi daire4 = new ApartmanDairesi();
		daire4.celikKapiliMi = true;
		daire4.duvarRengi = "Yeşil";
		daire4.odaSayisi = 1;
		
	}
}

Burada peşpeşe iki method çağrısı yapmış bulunmaktayız. Çıktı olarak bu methodların aynı işi yaptığını söyleyebiliriz. Ancak görüldüğü üzere alanların değer değişiklikleri, insaat2() methodunda setterlar vasıtasıyla yapılmaktadır. Peki ilk haline göre neler değişti?

  • Bir değerin get edilmesini veya set edilmesini bir methoda bıraktık. Yani okunmasını ve yazmasını kontrol altına aldık. Buna encapsulation veya sarmalama/kapsülleme/paketleme ismi verilmektedir.
  • Bir değerin sınıf içerisinde farklı okunurken sınıf dışında farklı okunmasına imkan verdik. Örneğin inşaat sınıfı duvar rengi olarak tüm yeşil tonlarını dış sınıflara yeşil dönerken, sınıf içerisinde farklı tonlarla işlem yapabilir. Bir eve perde alırken duvar rengi ton olarak çok büyük mesele teşkil etmeyebilir. Ancak duvarın bir parçasını daha boyayacaksanız önemli olabilir. Bu yüzden bazı noktalarda ayrım, bazı noktalarda genel geçer cevaplar gereklidir.
  • Kodun debug edilmesi sırasında değer değişikliklerinin takibi için güvenilir bir nokta oluşturduk. Böylece değişikliğin tek sınıfın tek noktasında gerçekleştiğini garanti altına almış olduk.

Getter ve setter kullanımının yararları aslında burada görüldüğünden daha fazladır. Ancak bunu daha iyi yorumlamak için farklı bir konuyu da anlamaya ihtiyaç vardır. Bu konu ise access modifiers yani erişim düzenleyicilerdir. Her ne kadar yukarıdaki örnekte getter ve setterlar oluşturmuş olsak da, örneğimiz bu haliyle eksik kalmakta ve amaca tam olarak hizmet etmemektedir.

Bir sonraki yazımızda erişim düzenleyicileri konusuna değineceğiz ve yukarıdaki kodun neden eksik kaldığına dair örnekler yapacağız.

1 Comment

Leave a Comment

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