Menu
CoddyTech

Class Generik

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

Sebuah class juga dapat memiliki parameter tipe. Box<T> menyimpan nilai dengan tipe apa pun, dan setiap instance menetapkan tipenya: Box<Int> hanya menerima nilai Int:

class Box<T>(var value: T) {
    fun describe() = "box with $value"
}

Di dalam main:

val numberBox = Box(42)
val textBox = Box("hello")
numberBox.value += 1
println(numberBox.describe())
println(textBox.describe())
// numberBox.value = "x"   // error: String bukan Int

Output:

box with 43
box with hello

Container adalah class generik yang umum. Satu implementasi Stack<T> berfungsi untuk setiap tipe elemen, dan compiler memeriksa apa yang masuk dan keluar:

class Stack<T> {
    private val items = mutableListOf<T>()
    val size: Int
        get() = items.size

    fun push(item: T) { items.add(item) }
    fun pop(): T? = items.removeLastOrNull()
    fun peek(): T? = items.lastOrNull()
}

Di dalam main:

val stack = Stack<String>()
stack.push("a")
stack.push("b")
println(stack.pop())
println(stack.peek())
println(stack.size)

Output:

b
a
1

Argumen tipe disimpulkan dari argumen konstruktor jika ada, seperti pada Box(42). Jika tidak, tuliskan secara eksplisit: Stack<String>(). Instance dengan argumen tipe yang berbeda adalah tipe yang berbeda, jadi Stack<String> tidak akan pernah tertukar dengan Stack<Int>. Fungsi dari generic class juga dapat menambahkan parameter tipe sendiri:

class Box<T>(val value: T) {
    fun <R> map(f: (T) -> R): Box<R> = Box(f(value))
}

Di dalam main:

val length = Box("kotlin").map { it.length }
println(length.value + 1)

Output:

7

Interface generik mengikuti aturan yang sama. Sebuah class dapat mengimplementasikannya secara generik, atau untuk satu argumen tipe tertentu:

interface Repository<T> {
    fun add(item: T)
    fun all(): List<T>
}
class MemoryRepository<T> : Repository<T> {
    private val items = mutableListOf<T>()
    override fun add(item: T) { items.add(item) }
    override fun all() = items.toList()
}
class TagRepository : Repository<String> {
    private val tags = sortedSetOf<String>()
    override fun add(item: String) { tags.add(item.lowercase()) }
    override fun all() = tags.toList()
}

Di dalam main:

val ids = MemoryRepository<Int>()
ids.add(3); ids.add(1)
val tags = TagRepository()
tags.add("Kotlin"); tags.add("JVM")
println("${ids.all()} ${tags.all()}")

Output:

[3, 1] [jvm, kotlin]
challenge icon

Tantangan

Mudah

Tulis class generik History<T>(limit) yang mengingat item-item terakhir sebanyak limit. add(item) menambahkan item dan membuang item terlama jika jumlahnya lebih dari limit. latest adalah item terbaru atau null, dan all() mengembalikan item dari yang terlama hingga terbaru sebagai list hanya-baca. Lalu, tulis fungsi ekstensi History<Int>.average(), yang hanya tersedia untuk riwayat angka dan mengembalikan rata-rata bilangan bulat dari angka-angka yang tersimpan (0 jika kosong).

Kode yang disediakan membaca batas, satu baris kata, dan satu baris angka. Kode ini mengisi History<String> dan History<Int>, lalu mencetak kata-kata yang tersimpan, kata terbaru, angka-angka yang tersimpan, rata-ratanya, dan empty latest: null.

Tulis kodemu di History.kt. Main.kt berisi kode input/output yang disediakan dan tidak dapat diedit.

Coba sendiri

fun main() {
    // Kode input/output yang disediakan: biarkan tetap seperti ini
    val input = generateSequence(::readLine).toList()
    val limit = input[0].toInt()
    val words = History<String>(limit)
    for (w in input[1].split(" ")) words.add(w)
    val numbers = History<Int>(limit)
    for (n in input[2].split(" ")) numbers.add(n.toInt())
    println("words: ${words.all()}")
    println("latest word: ${words.latest}")
    println("numbers: ${numbers.all()}")
    println("average: ${numbers.average()}")
    println("empty latest: ${History<Char>(3).latest}")
}
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