Menu
Coddy logo textTech

Uzantı Fonksiyonları

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

Uzantı işlevi, türün kaynak kodunu değiştirmeden mevcut bir türe işlev ekler. Adı alıcı türden sonra yazılır ve işlevin içinde this, alıcıyı ifade eder; alıcı ayrıca yazılmayabilir:

fun String.shout() = uppercase() + "!"
fun Int.isEven() = this % 2 == 0

main içinde:

println("hello".shout())
println(7.isEven())
println(listOf(1, 2, 3, 4).count { it.isEven() })

Çıktı:

HELLO!
false
2

Uzantılar kendi sınıflarınız üzerinde de çalışır ve uzantı özellikleri hesaplanan özellikler ekler. Bir uzantı depolanan durum ekleyemez ve yalnızca alıcısının herkese açık üyelerine erişebilir:

class Temperature(val celsius: Double)

val Temperature.fahrenheit: Double
    get() = celsius * 9 / 5 + 32

fun Temperature.describe() = "$celsius C is $fahrenheit F"

main içinde:

println(Temperature(100.0).describe())

Çıktı:

100.0 C is 212.0 F

Uzantılar statik olarak çözümlenir: ifadede bildirilen tür, uzantıyı nesnenin sınıfına göre değil, program derlendiğinde belirler. Bu, geçersiz kılınmış bir üyeden temel farkıdır:

open class Shape {
    open fun member() = "shape member"
}
class Circle : Shape() {
    override fun member() = "circle member"
}

fun Shape.ext() = "shape extension"
fun Circle.ext() = "circle extension"

main içinde:

val s: Shape = Circle()
println(s.member())
println(s.ext())

Çıktı:

circle member
shape extension

Sınıf zaten aynı imzaya sahip bir üyeye sahip olduğunda, üye her zaman önceliklidir. Türe ait olan ve üzerine yazılabilen davranışlar için üyeleri; dışarıdan eklenen yardımcılar için, örneğin sahibi olmadığın bir sınıf için biçimlendirme amacıyla uzantıları kullan:

class Robot {
    fun greet() = "member greet"
}

fun Robot.greet() = "extension greet"
fun Robot.wave() = "extension wave"

main içinde:

val r = Robot()
println(r.greet())
println(r.wave())

Çıktı:

member greet
extension wave
challenge icon

Görev

Kolay

Money(cents), Money.kt dosyasında sağlanmıştır. Bunun için uzantıları MoneyExtensions.kt dosyasına yazın: bir sayıyı Money'ye dönüştüren Int.dollars ve Int.cents uzantı özellikleri (12.dollars 1200 centtir), $12.50 (veya negatif miktarlar için -$3.05) döndüren Money.format(), toplamı Money olarak döndüren List<Money>.total() ve aralarında en fazla bir cent fark bulunan, büyük miktarların önce geldiği parts adet miktara bölen Money.split(parts).

Sağlanan kod, 12 dollars veya 50 cents satırlarını ve son satırda parça sayısını okur. Her miktarı, total: $12.50 ve split 3: $4.17 $4.17 $4.16 ifadelerini yazdırır.

Kodunuz MoneyExtensions.kt ve Money.kt dosyalarına gider. 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 amounts = input.dropLast(1).map { line ->
        val (n, unit) = line.split(" ")
        if (unit == "dollars") n.toInt().dollars else n.toInt().cents
    }
    for (m in amounts) println(m.format())
    val total = amounts.total()
    println("total: ${total.format()}")
    val parts = input.last().toInt()
    println("split $parts: " + total.split(parts).joinToString(" ") { it.format() })
}
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