Menu
CoddyTech

Pemanggilan Dinamis

Termasuk bagian Pemrograman Berorientasi Objek dalam perjalanan Kotlin di Coddy. Pelajaran 27 dari 57.

Polymorphism berarti satu pemanggilan dapat berperilaku dengan banyak cara. Saat kamu memanggil method yang ditimpa melalui tipe superclass atau interface, Kotlin melihat class aktual object saat program berjalan, lalu menjalankan versinya dari class tersebut. Ini disebut dynamic dispatch:

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"
}

Di dalam main:

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

Output:

Rex: Woof
Bess: Moo
Fido: Woof

Kode pemanggil tidak berubah saat subclass baru muncul. totalArea di bawah ditulis untuk semua Shape, jadi kode ini juga berfungsi dengan Triangle, meskipun tidak ada yang mengubahnya:

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() }

Di dalam main:

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

Output:

10.0

Dispatch melihat object, bukan variabelnya. Menetapkan object lain ke variabel yang sama akan mengubah kode yang dijalankan pada pemanggilan berikutnya:

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() + "!"
}

Di dalam main:

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

Output:

hello
HELLO!

Polimorfisme menggantikan pemeriksaan seperti if (kind == "dog") yang jika tidak, akan diulang di setiap tempat hewan digunakan. Setiap class memiliki perilakunya sendiri, dan untuk menambahkan jenis hewan, kamu hanya perlu menambahkan satu class:

// tanpa polimorfisme: setiap fungsi memeriksa jenisnya
fun sound(kind: String) = when (kind) { "dog" -> "Woof"; "cow" -> "Moo"; else -> "?" }

// dengan polimorfisme: jenis baru memiliki perilakunya sendiri
class Sheep(name: String) : Animal(name) {
    override fun sound() = "Baa"
}
challenge icon

Tantangan

Mudah

Character(name, hp) adalah class terbuka. takeHit(damage) mengurangi hp dengan damage (tidak pernah kurang dari 0), dan status() mengembalikan Ada: 30 hp atau Ada: down saat nilainya 0. hp dapat dibaca di mana saja, tetapi hanya dapat diubah di dalam Character. Lengkapi subclass dengan meng-override takeHit dan meneruskan damage yang telah diubah ke super.takeHit: Warrior (40 hp) menerima setengah damage, dibulatkan ke bawah; Mage (25 hp) memiliki perisai yang menyerap seluruh damage dari serangan pertama; Rogue (30 hp) menghindari setiap serangan kedua yang diterimanya (ke-2, ke-4, ...).

Kode yang disediakan membaca party sebagai warrior:Ada,mage:Bo,rogue:Cy, lalu memberikan serangan dengan all 10 atau Ada 12. Kode tersebut memanggil takeHit melalui tipe Character, lalu mencetak setiap status().

Tempatkan kodemu di Character.kt, Warrior.kt, Mage.kt, dan Rogue.kt. Main.kt berisi kode input/output yang disediakan dan tidak dapat diedit.

Coba sendiri

fun main() {
    // Kode input/output yang disediakan: biarkan apa adanya
    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 iconUji dirimu

Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.

Semua pelajaran di Pemrograman Berorientasi Objek

Latihan sendiri: Playground Kotlin