Menu
Coddy logo textTech

Dinamik Gönderim

Coddy'nin Kotlin Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 27 / 57.

Polimorfizm, tek bir çağrının birçok şekilde davranabilmesi anlamına gelir. Ezilmiş bir metodu üst sınıf veya arayüz türü üzerinden çağırdığında Kotlin, program çalışırken nesnenin gerçek sınıfına bakar ve o sınıfın sürümünü çalıştırır. Buna dinamik gönderim denir:

abstract class Animal(val name: String) {
    abstract fun sound(): String
    fun speak() = "$name: ${sound()}"
}
class Dog(name: String) : Animal(name) {
    override fun sound() = "Woof"
}
class Cow(name: String) : Animal(name) {
    override fun sound() = "Moo"
}

main içinde:

val barn: List<Animal> = listOf(Dog("Rex"), Cow("Bess"), Dog("Fido"))
for (a in barn) println(a.speak())

Çıktı:

Rex: Woof
Bess: Moo
Fido: Woof

Yeni bir alt sınıf ortaya çıktığında çağıran kod değişmez. Aşağıdaki totalArea herhangi bir Shape için yazılmıştır; bu nedenle kimse değiştirmemiş olsa da Triangle ile de çalışır:

interface Shape {
    fun area(): Double
}
class Square(val side: Double) : Shape {
    override fun area() = side * side
}
class Triangle(val base: Double, val height: Double) : Shape {
    override fun area() = base * height / 2
}

fun totalArea(shapes: List<Shape>) = shapes.sumOf { it.area() }

main içinde:

println(totalArea(listOf(Square(2.0), Triangle(3.0, 4.0))))

Çıktı:

10.0

Dispatch değişkene değil, nesneye bakar. Aynı değişkene başka bir nesne atamak, sonraki çağrıda hangi kodun çalışacağını değiştirir:

interface Mode {
    fun format(text: String): String
}
class Normal : Mode {
    override fun format(text: String) = text
}
class Shout : Mode {
    override fun format(text: String) = text.uppercase() + "!"
}

main içinde:

var mode: Mode = Normal()
println(mode.format("hello"))
mode = Shout()
println(mode.format("hello"))

Çıktı:

hello
HELLO!

Polimorfizm, hayvanların kullanıldığı her yerde aksi takdirde tekrarlanacak olan if (kind == "dog") gibi kontrollerin yerini alır. Her sınıf kendi davranışını korur ve yeni bir hayvan türü eklemek, bir sınıf eklemek anlamına gelir:

// polimorfizm olmadan: her fonksiyon türü kontrol eder
fun sound(kind: String) = when (kind) { "dog" -> "Woof"; "cow" -> "Moo"; else -> "?" }

// polimorfizm ile: yeni tür kendi davranışını getirir
class Sheep(name: String) : Animal(name) {
    override fun sound() = "Baa"
}
challenge icon

Görev

Kolay

Character(name, hp) açık bir sınıftır. takeHit(damage), hasarı hp değerinden çıkarır (0'ın altına asla düşmez) ve status(), 0'da Ada: 30 hp veya Ada: down döndürür. hp her yerden okunabilir, ancak yalnızca Character içinde değiştirilebilir. Alt sınıfları takeHit metodunu geçersiz kılarak ve değiştirilen hasarı super.takeHit metoduna aktararak tamamla: Warrior (40 hp) hasarın aşağı yuvarlanmış hâlinin yarısını alır; Mage (25 hp), aldığı ilk vuruşun tamamını emen bir kalkana sahiptir; Rogue (30 hp) aldığı her ikinci vuruştan kaçar (2., 4., ...).

Sağlanan kod, grubu warrior:Ada,mage:Bo,rogue:Cy olarak okur ve ardından all 10 veya Ada 12 ile vuruş yapar. takeHit metodunu Character türü üzerinden çağırır ve son olarak her status() sonucunu yazdırır.

Kodun Character.kt, Warrior.kt, Mage.kt ve Rogue.kt dosyalarına yazılır. Main.kt, sağlanan girdi/çıktı kodunu içerir ve düzenlenemez.

Kendin dene

fun main() {
    // Sağlanan girdi/çıktı kodu: olduğu gibi bırakın
    val input = generateSequence(::readLine).toList()
    val party = input[0].split(",").map { spec ->
        val (kind, name) = spec.split(":")
        when (kind) {
            "warrior" -> Warrior(name)
            "mage" -> Mage(name)
            else -> Rogue(name)
        }
    }
    for (cmd in input.drop(1)) {
        val (target, damage) = cmd.split(" ")
        for (c in party) {
            if (target == "all" || target == c.name) c.takeHit(damage.toInt())
        }
    }
    for (c in party) println(c.status())
}
quiz iconKendini test et

Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.

Nesne Yönelimli Programlama bölümündeki tüm dersler

Kendi başına pratik yap: Kotlin playground