Bazen aynı işlemleri farklı sınıf veya metotta yapabiliriz. Bu da uygulamamızda fazladan kod veya kod yükü yaratabilir. Generic sınıf ve metot ile bu sorunu çözebiliriz.

Öncelikle generic sınıf için örnek verelim. Int tipinde bir dizimiz olsun ve bunu ekrana metotla yazdırmak isteyelim. Ayrıca ikinci olarak String tipinde bir dizimiz olsun onu da ekrana metot kullanarak yazdıralım.

class IntDizi(var gelenDizi : Array<Int>)
{
    fun diziYazdir()
    {
        for(i in gelenDizi)
        {
            println(i)
        }
    }   
}

class StringDizi(var gelenDizi : Array<String>)
{
    fun diziYazdir()
    {
        for(i in gelenDizi)
        {
            println(i)
        }
    }
}

fun main(args: Array<String>)
{
    var dizi1 = arrayOf(1,2,3,4)
    
    var diziY : IntDizi = IntDizi(dizi1)
    diziY.diziYazdir()
    
    
    var dizi2 = arrayOf("Barış", "Andrei", "Lavi")
    
    var diziY2 : StringDizi = StringDizi(dizi2)
    diziY2.diziYazdir()
    
}


Görüldüğü üzere aynı dizi işlemi yapmama rağmen tür farkı olduğundan sınıfları ayrı ayrı tanımlamak zorunda kaldım. Generic sınıf sayesinde bu sorunu ortadan kaldıracağız. StringDizi sınıfımız <String> türünde dizi kabul ederken, IntDizi sınıfımız <Int> türünde dizi kabul etmektedir. Bunları genel yaparsak ortadan sorun kalkacak ve kod fazlalığından kurtulacağız. 

class GenelDizi<Genel>(var gelenDizi : Array<Genel>) // Genel yerine herhangi bir tür yazılabilir..
{
    fun diziYazdir()
    {
        for(i in gelenDizi)
        {
            println(i)
        }
    }   
}


fun main(args: Array<String>)
{
    var dizi1 = arrayOf(1,2,3,4)
    var dizi2 = arrayOf("Barış", "Andrei", "Lavi")
    
    var diziY  = GenelDizi(dizi1)
    diziY.diziYazdir()
    
    var diziY2 = GenelDizi(dizi2)
    diziY2.diziYazdir()    
}


Burada GenelDizi sınıfımızı genelleştirerek herhangi bir tür kabul ettik. <Genel> yerine string bir dizi gönderilse String dönecek, Int gelirse Int dönecek. “Genel” sözcüğünü istediğiniz gibi tanımlayabilirsiniz.

Şimdi, generic metotlar için de örnek verip yazımızı bitirelim. Abstract classlar ve metotlarda anlattığım Geometrik Şekil, Kare ve Dikdörtgen örneğini buraya uyarlamak istiyorum. Dilerseniz, Abstract Class ve Metotlara buradan ulaşabilirsiniz.

abstract class GeometrikSekil
{
    abstract fun alanHesapla() : Int
}

open class Kare(var kenar : Int):GeometrikSekil()
{
    override fun alanHesapla() : Int
    {
        return kenar*kenar
    }
}

class Dikdortgen(var kKenar : Int, var bKenar:Int):GeometrikSekil()
{
    override fun alanHesapla() : Int
    {
        return kKenar*bKenar
    }
}

fun main(args: Array<String>)
{
    var kare1 : Kare = Kare(5)
    var kare2 : Kare = Kare(6)
    
    println("kare1 = "+ kare1.alanHesapla())
    println("kare2 = " + kare2.alanHesapla())
    println("Maximum Kare Alan = " + KareAlanMax(kare1,kare2).alanHesapla())
    
    var dikdortgen1 : Dikdortgen = Dikdortgen(7,3)
    var dikdortgen2 : Dikdortgen = Dikdortgen(3,4)
    
    println("dikdortgen1 = " + dikdortgen1.alanHesapla())
    println("dikdortgen2 = " +  dikdortgen2.alanHesapla())
    println("Maximum Dikdortken Alan = " + DikdortgenAlanMax(dikdortgen1, dikdortgen2).alanHesapla())
    
    
    
}


fun KareAlanMax(k1:Kare, k2:Kare) : Kare
{
    if(k1.alanHesapla()>k2.alanHesapla())
    return k1
    
    else
    return k2
    
}

fun DikdortgenAlanMax(d1:Dikdortgen, d2:Dikdortgen) : Dikdortgen
{
    if(d1.alanHesapla() > d2.alanHesapla())
    return d1
    
    else
    return d2
   
}


Görüldüğü üzere KareAlanMax() ve DikDortgenAlanMax() metotlarında aslında aynı işlemleri yapıyorum, ancak metodun döndürdüğü veri tipleri farklı. Bir tanesi Dikdortgen sınıfından değer döndürürken diğeri de Kare sınıfından değer döndürüyor. İşte generic metot tanımlayarak bu kod tekrarını ortadan kaldırabiliriz.

abstract class GeometrikSekil
{
    abstract fun alanHesapla() : Int
}

open class Kare(var kenar : Int):GeometrikSekil()
{
    override fun alanHesapla() : Int
    {
        return kenar*kenar
    }
}

class Dikdortgen(var kKenar : Int, var bKenar:Int):GeometrikSekil()
{
    override fun alanHesapla() : Int
    {
        return kKenar*bKenar
    }
}

fun main(args: Array<String>)
{
    var kare1 : Kare = Kare(5)
    var kare2 : Kare = Kare(6)
    
    println("kare1 = "+ kare1.alanHesapla())
    println("kare2 = " + kare2.alanHesapla())
    println("Maximum Kare Alan = " + MaxAlan(kare1,kare2).alanHesapla())
    
    var dikdortgen1 : Dikdortgen = Dikdortgen(7,3)
    var dikdortgen2 : Dikdortgen = Dikdortgen(3,4)
    
    println("dikdortgen1 = " + dikdortgen1.alanHesapla())
    println("dikdortgen2 = " +  dikdortgen2.alanHesapla())
    println("Maximum Dikdortken Alan = " + MaxAlan(dikdortgen1, dikdortgen2).alanHesapla())
    
    
    
}

fun MaxAlan(s1:GeometrikSekil, s2:GeometrikSekil) : GeometrikSekil // süper sınıf olan GeometrikSekil'den türettik
{
    if(s1.alanHesapla()>s2.alanHesapla())
    return s1
    
    else
    return s2
}


MaxAlan() metodumuzu Kare ve Dikdörtgenin süper sınıfı (üst sınıfı) olan GeometrikSekilden türettik ve dönecek olan değer hem Kare hem de Dikdortgen kabul edebilir. Çünkü Kare ve Dikdörtgenin en üst sınıfı GeometrikSekil sınıfı idi. Dolayısıyla, kod tekrarını bu şekilde kaldırmış olduk.