Kotlin Polymorphism: Detaylı Rehber ve Kod Örnekleri

Başlatan Kasne, Nis 07, 2025, 12:52 ÖS

« önceki - sonraki »

Kasne


Kotlin, modern ve güçlü bir programlama dili olarak, nesne yönelimli programlamanın (OOP) temel prensiplerini destekler. Bu prensiplerden biri olan polymorphism (çok biçimlilik), Kotlin'de kod yazmayı esnek ve yeniden kullanılabilir hale getiren önemli bir özelliktir. Bu rehberde, Kotlin'de polymorphism mantığını detaylı bir şekilde ele alacak, kod örnekleriyle açıklayacak ve SEO uyumlu bir içerik sunacağız. Kotlin ile uygulama geliştiriyorsanız veya bu konuyu öğrenmek istiyorsanız, doğru yerdesiniz!

Polymorphism Nedir?
Polymorphism, bir nesnenin farklı türlerde davranabilmesini sağlayan bir özelliktir. Türkçe'de "çok biçimlilik" olarak bilinen bu kavram, bir üst sınıfın (superclass) metodlarının alt sınıflar (subclass) tarafından farklı şekillerde uygulanmasına olanak tanır. Kotlin'de polymorphism, compile-time (derleme zamanı) ve runtime (çalışma zamanı) olmak üzere iki şekilde karşımıza çıkar.

  • Compile-Time Polymorphism: Metot overloading (aşırı yükleme) ile sağlanır.
  • Runtime Polymorphism: Metot overriding (geçersiz kılma) ve inheritance (kalıtım) ile gerçekleştirilir.

Kotlin'de Compile-Time Polymorphism (Metot Aşırı Yükleme)
Metot overloading, aynı isimde ancak farklı parametre listelerine sahip birden fazla metot tanımlamanıza olanak tanır. Derleyici, hangi metodun çağrılacağına parametre türüne ve sayısına göre karar verir.

class Hesaplayici {
    fun topla(a: Int, b: Int): Int {
        return a + b
    }

    fun topla(a: Double, b: Double): Double {
        return a + b
    }

    fun topla(a: Int, b: Int, c: Int): Int {
        return a + b + c
    }
}

fun main() {
    val hesap = Hesaplayici()
    println(hesap.topla(5, 3))        // Çıktı: 8
    println(hesap.topla(2.5, 3.7))    // Çıktı: 6.2
    println(hesap.topla(1, 2, 3))     // Çıktı: 6
}


Yukarıdaki örnekte, topla metodu farklı parametrelerle aşırı yüklenmiştir. Kotlin, çağrılan parametre türüne göre doğru metodu seçer.

Kotlin'de Runtime Polymorphism (Metot Geçersiz Kılma)
Runtime polymorphism, bir üst sınıfın metodunun alt sınıfta yeniden tanımlanmasıyla (override) sağlanır. Bu durumda, hangi metodun çalışacağına çalışma zamanında nesnenin türüne göre karar verilir.

open class Hayvan {
    open fun sesCikar() {
        println("Bu bir hayvan sesi!")
    }
}

class Kedi : Hayvan() {
    override fun sesCikar() {
        println("Miyav!")
    }
}

class Kopek : Hayvan() {
    override fun sesCikar() {
        println("Hav hav!")
    }
}

fun main() {
    val hayvan: Hayvan = Kedi()
    hayvan.sesCikar()  // Çıktı: Miyav!

    val kopek: Hayvan = Kopek()
    kopek.sesCikar()   // Çıktı: Hav hav!
}

Bu örnekte:
  • Hayvan sınıfı open anahtar kelimesiyle tanımlanmıştır, böylece kalıtıma ve metod geçersiz kılmaya izin verir.
  • sesCikar metodu alt sınıflarda (Kedi ve Kopek) override edilmiştir.
  • Nesnenin türüne bağlı olarak farklı çıktılar üretilir.

Interface ile Polymorphism
Kotlin'de polymorphism, yalnızca sınıflar değil, interface'ler aracılığıyla da uygulanabilir. Birden fazla sınıf, aynı interface'i implemente ederek farklı davranışlar sergileyebilir.

interface UlasimAraci {
    fun hareketEt()
}

class Araba : UlasimAraci {
    override fun hareketEt() {
        println("Araba yolda gidiyor.")
    }
}

class Bisiklet : UlasimAraci {
    override fun hareketEt() {
        println("Bisiklet pedal çeviriyor.")
    }
}

fun main() {
    val arac1: UlasimAraci = Araba()
    val arac2: UlasimAraci = Bisiklet()

    arac1.hareketEt()  // Çıktı: Araba yolda gidiyor.
    arac2.hareketEt()  // Çıktı: Bisiklet pedal çeviriyor.
}


Bu kodda, UlasimAraci interface'ini implemente eden Araba ve Bisiklet sınıfları, hareketEt metodunu farklı şekillerde tanımlar.

Polymorphism'in Avantajları Nelerdir?
  • Esneklik: Aynı kod yapısı farklı nesnelerle çalışabilir.
  • Kod Tekrarını Azaltma: Tek bir arayüz veya üst sınıf üzerinden farklı davranışlar tanımlanabilir.
  • Bakım Kolaylığı: Kodunuzu genişletmek ve değiştirmek daha kolay hale gelir.

Pratik Örnek: Polymorphism ile Geometrik Şekiller
Şimdi, polymorphism'i kullanarak bir geometrik şekil örneği yapalım:

open class Sekil {
    open fun alanHesapla(): Double {
        return 0.0
    }
}

class Kare(val kenar: Double) : Sekil() {
    override fun alanHesapla(): Double {
        return kenar * kenar
    }
}

class Daire(val yaricap: Double) : Sekil() {
    override fun alanHesapla(): Double {
        return Math.PI * yaricap * yaricap
    }
}

fun main() {
    val sekiller: List<Sekil> = listOf(Kare(4.0), Daire(3.0))
    for (sekil in sekiller) {
        println("Alan: ${sekil.alanHesapla()}")
    }
}


Çıktı:

Alan: 16.0
Alan: 28.274333882308138


Bu örnekte, Sekil üst sınıfından türeyen Kare ve Daire sınıfları, alanHesapla metodunu kendi ihtiyaçlarına göre özelleştirir.

Sonuç
Kotlin'de polymorphism, kodunuzu daha dinamik ve yeniden kullanılabilir hale getiren güçlü bir araçtır. Metot aşırı yükleme ile derleme zamanında, kalıtım ve metot geçersiz kılma ile çalışma zamanında çok biçimliliği uygulayabilirsiniz. Interface'ler ise bu esnekliği bir adım öteye taşır. Bu rehberdeki örnekleri deneyerek Kotlin polymorphism mantığını daha iyi kavrayabilir, kendi projelerinizde uygulayabilirsiniz.