"Enter"a basıp içeriğe geçin

Generic

 

Şimdiye kadar sınıflarımıza veya fonksiyonlarımıza bir özellik yazdığımızda tek bir veri türü için tanımlanmış oluyordu.

Mesela 4 işlem yapan bir sınıf yazdık. Eğer sınıfımızda değişkenlerin türlerini ve dönüş tiplerini int yazarsak, sınıfımız sadece int veri tipi için 4 işlem yapabilirdi. Double için farklı bir sınıf yazmamız gerekirdi.

Veya yazdırma yapan bir fonksiyonumuz olsun. Eğer bu fonksiyonu int için yazmışsak ve string bir değer gönderirsek hata alırdık.

Sonuç olarak sınıfımız ve fonksiyonlarımız tek bir veri tipine mahkumdu.

Genericler bu durumu değiştirmede kullanılmaktadır. Generic bir fonksiona int yollarsak int veri tipine göre işlem yapar. Double yollarsak double’a göre, string yollarsak stringe göre işlem yapar. Yani sınıf ve fonksiyonlarımız artık türden bağımsız olur.

Eski durumu gösteren bir kod yazalım.

Yapılan işlemler ve yazılan kodlar neredeyse aynı. Fonksiyonlardaki tek değişen şey veri tipleri. Yani her veri tipi için fonksiyonu yeniden tanımlamamız gerekti. 4. bir veri eklemek isteseydik onun için de fonksiyonu tekrar yazacaktık.

Bunun yerine generic kullanarak kodu aşağıdaki gibi yazabiliriz.

Buradaki <T> ifadesi generic demektir. Parametre kısmında gelen değişken bir veri tipinde değil <T> şeklinde bunun anlamı, parametre olarak gelen değişkenin tipi T değerini belirler.

Yani eğer parameter olarak Integer yollarsak T yerine Integer yazılır. String yollarsak T=String olur. Kodun geri kalanında da bu belirlenen veri tipi T görülen her yere yazılır.

Yaz(dizi1); olarak çağırdığımızda bir Integer değer yolladık. Bu durumda fonksiyonda T görülen her yere Integer yazıldı. Yani kodumuz Integer değerlere göre ayarlanmış oldu.
Yaz(dizi3); olarak çağrıldığında T String oldu ve kod stringe göre çalıştı.

Burada dikkat etmemiz gereken şey, T yerine konan tip bir referans olmalıdır. Temel tipler kabul edilmez. Aynı Arraylistlerde yaptığımız gibi int ve double yerine bunların referans değerleri olan Integer ve Double yolladık.

 

Fonksiyona yolladığımız şey bir sınıf da olabilir. Ancak normalde sınıf nesnelerini System.out.println(); ile yazdıramayız. Çünkü println fonksiyonu sadece Java dilinde önceden tanımlı olan nesne ve tipleri yazdırmak için ayarlanmıştır.

Java dilinde tüm sınıflar aslında otomatik olarak Object sınıfından türer. Object sınıfı tüm sınıfların atası olduğundan, tüm yazılan sınıflarda bizim eklemediğimiz bazı fonksiyonlar bulunur. Ve bu fonksiyonları override edebiliriz. Bunlardan biri toString fonksiyonudur. Bu fonksiyon string döndürür. println() fonksiyonu da string aldığından, toString fonksiyonunu override edersek println() fonksiyonu nesneleri yazdırabilir.

Bir örnek yapalım.

Abstract Canlı Sınıfı

 

İnsan Sınıfı

 

Main sınıfı

println( İnsan1 ) dediğimizde toString fonksiyonu çağrılır, println() ile yazılabilir.

Normalde generic metodların içinde T’ye bağlı üye fonksiyon kullanamayız. Mesela İnsan sınıfındaki getInfo metodunu aşağıdaki şekilde kullanamız mümkün değildir.

Çünkü T yerine her şey gelebilir. Ve T yerine gelen nesnenin içinde getInfo metodu olduğu garanti edilemez. Gelen bir int de olabilir. int için int.getInfo şeklinde birşey yazmak mümkün değildir.

Ancak generic metodumuzu belli Abstract veya Interface’ler için çalışacak şekilde sınırlayabilir ve kodumuzun içinde bu yapılardaki fonksiyonları kullanabiliriz. Çünkü abrstacttan türeyen tüm sınıflarda o fonksiyonun olduğu garanti edilebilir.

public static <T extends Canlı> void info (T x) dersek, parametre olarak gelen şey, Canlı sınıfından türeyen bir sınıfın nesnesi olmalıdır. Ve bu sınıfta o fonksiyonların tanımlı olduğunu garanti edebiliriz.

 

 

 

İleride göreceğimiz Arraylist gibi konteyner sınıflar da generic sınıf olduklarından, ne yollanırsa kendilerini ona göre ayarlarlar.

Kendimiz de basit bir konterner sınıf oluşturup tek bir basit metod ekleyelim.

MyArray Sınıfı

Main Sınıfı

Myarray sınıfını oluşturduk. Ancak tıpkı fonksiyonlarda olduğu gibi, Myarray sınıfı da sadece int değerleri tutabilir. Generic kullanarak tüm tipleri tutabilecek hale getirebiliriz.

Generic sınıflarda constructor içinde T yerine hangi tür geliyorsa constructor içinde T yerine o konur. Ama eğer sınıftaki bir metodda E konursa, o metodun içindeki T’ler metoda yollanan türde olur.

MyArray Sınıfı

Main

Amacımıza ulaştık.

    Bir cevap yazın

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