Java Generics – Tipler Üzerinde Soyutlaşma

Generics?

Aslında konunun başlığı genel anlamda konuyu özetliyor (en azından sadece bir kısmını :)). Java 1.5 versiyonuyla gelen Generics özelliği, yazdığımız sınıfı tipler üzerinde soyutlaştırmamızı, türden bağımsız sınıflar yaratabilmemizi sağlıyor. Yani, sınıfı yazarken sınıfın metotlarının birden fazla tip için çalışabilirliğini sağlamış oluyoruz.

En güzel anlatım örnekle anlatımdır diyerek (tamamen kendi görüşüm :)) bir örnek üzerinde gösterelim. Örneğin, ArrayList sınıfı. Aslında 1.2 versiyonundan beri Generics özelliğinden mahrum olarak Java’da mevcut bir sınıf. İçerisinde tüm nesneleri tutabilen bir liste. İçerisinden istenilen tipi barındırabilmek ilk bakışta çok cazip gelse de aslında çok sakat(!) bir işlem. Bu konuya daha sonra değineceğim. Burada sadece örnek veriyorum.

Apple anApple = new Apple();
Pear aPear = new Pear();
       
ArrayList ourBag = new ArrayList();
ourBag.add(anApple);
ourBag.add(aPear);

Görüldüğü üzere elma ile armutu bir araya koyduk. ArrayList sınıfının eski halinde add metodu Object tipinde parametreye sahip olduğu için iki nesneyi de ekleyebildik.

add (Object o);

Şimdi de kendimizi biraz kısıtlayalım. Generics özelliğini kullanalım.

ArrayList<Apple> ourAppleBag = new ArrayList<Apple>();
ourAppleBag .add(anApple);
ourAppleBag .add(aPear); // Dikkat: derleyici izin vermez.

Oops. ArrayList‘in yanında Apple nesnesi var. Artık çantamıza sadece elma atabilir hale geldik (3. satıra derleyici izin vermeyecektir). Eğer, armutlarımızı tutmak istiyorsak yeni bir çanta almamız lazım.

ArrayList<Pear> ourPearBag = new ArrayList<Pear>();

Peki ne oldu? Neden birden kısıtladık kendimizi? Ayrıca türden bağımsızlık işin neresinde? Metodun parametresini Object türünde yaparsak tüm tipteki nesneleri alabilir değil mi artık?

Nimetler, Nimetler, Nimetler

Öncelikle elmayla armut aynı çantada olursa neler olur onu görelim. Parametre olarak bir ArrayList alan metodumuz olduğunu düşünelim.

getAppleJuice (ourBag);
// ...
public void getAppleJuice(ArrayList bag) {
        Apple anApple = bag.get(0);
}

Bu metodu derlemek istediğinizde derleyici hata vererek sizden cast işlemi yapmanızı isteyecektir. Çünkü;

Object get (int index);

get metodu Object tipinde bir nesne döndürüyor.

getAppleJuice (ourBag);
// ...
public void getAppleJuice(ArrayList bag) {
        Apple anApple = (Apple) bag.get(0);
}

Artık derleyici bize kızmıyor. Ama her zaman içinde elma olduğunu nereden bileceğiz. Şu durumu düşünelim;

getAppleJuice (ourBag);
// ...
public void getAppleJuice(ArrayList bag) {
        Apple anApple = (Apple) bag.get(1);
}

Derleyici için bir sorun yok. Programı çalıştırabilirsiniz. Hatta müşterinize satabilirsiniz. Bir süre sonra müşteriniz size elma suyu yerine armut suyu içtiğini, programın bozuk olduğunu söylerse şaşırmayın.

Gerçekte olan ise, programın çalışması anında Java bize kızar ve bir exception fırlatır. Buyrun size en güzelinden bir böcek.

E o zaman ArrayList sınıfına müdahele edelim ve Object olan yerleri Apple‘a çevirelim. Artık, getAppleJuice metodunun elma suyu döndürmesini garantilemiş olduk. Peki armutları tutmak için ne yapacağız? ArrayList sınıfını kopyalayacağız ve tüm Object olanları Pear yapacağız. Meyveler arttıkça kopya sınıflar da artmış oldu. Yeni her tip için sınıfı tekrar yazacağız.

Bu dertten kurtulmak gerekir. Bir kere yazalım hepsi için program anında bile düzgün çalışsın. Üstelik sadece 1 sınıfla!

Generics ile yazılmış ArrayList sınıfı ArrayList<E> şeklinde tanımlanıyor. Artık nesnesini oluştururken hangi sınıfı verirsek çantaya o nesneyi atabileceğiz. Yeni add metodu;

add (E e);

şeklinde. Artık parametre çanta yaratırken belirttiğimiz E tipinde.

ArrayList<Apple> ourAppleBag = new ArrayList<Apple>();
ourAppleBag.add(anApple);

Artık, çantamız bir elma çantası ve armut almıyor. Armut alan çanta için armut çantası yaratacağız.

Şimdi elma suyu metodumuza yeniden bakalım;

getAppleJuice (ourAppleBag);
// ...
public void getAppleJuice(ArrayList<Apple> bag) {
        Apple anApple = bag.get(1);
}

Biraz kısıtladık kendimizi değil mi? Ama program çalışırken ortaya çıkacak sürprizlerden kurtarmış olduk kendimizi. Artık metod aldığı çantanın bir elma çantası olduğunu biliyor. Cast işlemine de ihtiyaç duymuyor.

Sonuç?

Bu tarz her yazımda olduğu gibi yazının sonunda öneride bulunayım:

  • Halihazırdaki Java sınıflarını (özellikle ArrayList gibi Collection türündeki sınıfları) kullanırken Generics halini kullanın. Hatta diğer hali hiç kullanmayın 🙂
  • Eğer, kendi yazdığınız sınıf birden fazla tip için çalışacaksa tek ve doğru yolunuz Generics şeklinde yazmak.
9 Comments

    Java Generics – Tipler Üzerinde Soyutlaşma | Boğaç Aslanyürek

    […] sınıfı tipler üzerinde soyutlaştırmamızı, türden bağı… Devamı için : Java Generics – Tipler Üzerinde Soyutlaşma Like this:LikeBe the first to like this post. This entry was posted in Professional and tagged […]

    Java Generics – Tipler Üzerinde Soyutlaşma | Gökhan Tunçkale | Blog

    […] sınıfı tipler üzerinde soyutlaştırmamızı, türden bağı… Devamı için : Java Generics – Tipler Üzerinde Soyutlaşma ShareFacebookTwitterStumbleUponMoreTumblrRedditLinkedInDiggEmailPrintLike this:BeğenBe the first […]

    Java Generics – Tipler Üzerinde Soyutlaşma « Lé Blog

    […] sınıfı tipler üzerinde soyutlaştırmamızı, türden bağı… Devamı için : Java Generics – Tipler Üzerinde Soyutlaşma Share :FacebookTwitterStumbleUponLinkedInLike this:LikeBe the first to like this […]

    Java Generics – Tipler Üzerinde Soyutlaşma | Kara Kule

    […] sınıfı tipler üzerinde soyutlaştırmamızı, türden bağı… Devamı için : Java Generics – Tipler Üzerinde Soyutlaşma Share this:TwitterFacebookLike this:BeğenBe the first to like this post. By ahmet orsorlu […]

    Java Generics – Tipler Üzerinde Soyutlaşma « kodluyorum

    […] sınıfı tipler üzerinde soyutlaştırmamızı, türden bağı… Devamı için : Java Generics – Tipler Üzerinde Soyutlaşma Share this:TwitterFacebookLike this:BeğenBe the first to like this […]

    Java Generics – Tipler Üzerinde Soyutlaşma | yusufozkay

    […] sınıfı tipler üzerinde soyutlaştırmamızı, türden bağı… Devamı için : Java Generics – Tipler Üzerinde Soyutlaşma Share this:TwitterFacebookLike this:BeğenBe the first to like this post. This entry was posted […]

    punxlew

    tesekkurler, elinize saglik. Kolay anlasilir olmus.

      Ahmet Orsorlu

      Anlaşılır olmasına sevindim. İyi çalışmalar. Kolay gelsin.

    Zeynep

    gerçekten çok anlaşılır bir dille anlatmışsınız, çok teşekkürler yazılarınızın devamını bekleriz. Java ile ilgili özellikle ileri seviyelerde Türkçe kaynak bulmak biraz zor olabiliyor. Emeğinize sağlık başarılar..

Java Generics – Tipler Üzerinde Soyutlaşma | Gökhan Tunçkale | Blog için bir cevap yazın Cevabı iptal et