Menu
Coddy logo textTech

Własne akcesory

Część sekcji Programowanie obiektowe ścieżki Kotlin w Coddy. Lekcja 7 z 57.

Każda właściwość w Kotlinie ma getter, a każda właściwość var ma również setter. Domyślnie odczytują i zapisują przechowywaną wartość. Własny getter oblicza wartość przy każdym odczycie:

class Rectangle(var width: Int, var height: Int) {
    val area: Int
        get() = width * height
}

Wewnątrz main:

val r = Rectangle(3, 4)
println(r.area)
r.width = 10
println(r.area)

Wynik:

12
40

Niestandardowy setter uruchamia kod za każdym razem, gdy przypisywana jest wartość właściwości. Wewnątrz niego value to przypisywana wartość, a field to wartość przechowywana za właściwością, czyli pole zapasowe:

class Thermostat {
    var target = 20
        set(value) {
            field = value.coerceIn(10, 30)
        }
}

Wewnątrz main:

val t = Thermostat()
t.target = 42
println(t.target)
t.target = 18
println(t.target)

Wynik:

30
18

Wewnątrz akcesora używaj field, a nie nazwy właściwości: zapisanie target = value wewnątrz settera właściwości target wywołałoby setter ponownie, bez końca:

var target = 20
    set(value) {
        // target = value        // ponownie wywołuje ten setter: nieskończona rekurencja
        field = value             // przechowuje wartość
    }

Setter to również miejsce, w którym można reagować na zmiany, na przykład je zliczać lub zapisywać w logach:

class Player(name: String) {
    var changes = 0
        private set
    var name = name
        set(value) {
            field = value.trim()
            changes++
        }
}

Wewnątrz main:

val p = Player("ada")
p.name = "  Ada  "
p.name = "Ada L."
println("${p.name} after ${p.changes} changes")

Wynik:

Ada L. after 2 changes
challenge icon

Wyzwanie

Łatwy

Uzupełnij klasę Circle(radius: Double). radius to var, którego setter zapisuje wartości ujemne jako 0. Dodaj właściwości tylko do odczytu diameter i area (π r² z użyciem Math.PI) z własnymi getterami oraz label, która zwraca r=2.0 d=4.0 a=12.57, zaokrąglając pole do dwóch miejsc po przecinku ("%.2f".format(area)).

Dostarczony kod odczytuje jeden promień w każdym wierszu, wypisuje label, następnie podwaja promień ostatniego okręgu i ponownie wypisuje label, więc wartości muszą być zgodne z promieniem.

Umieść swój kod w Circle.kt. Main.kt zawiera dostarczony kod wejścia/wyjścia i nie można go edytować.

Spróbuj swoich sił

fun main() {
    // Dostarczony kod wejścia/wyjścia: pozostaw go bez zmian
    val input = generateSequence(::readLine).toList()
    var last = Circle(0.0)
    for (line in input) {
        last = Circle(line.toDouble())
        println(last.label)
    }
    last.radius *= 2
    println(last.label)
}
quiz iconSprawdź się

Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.

Wszystkie lekcje w sekcji Programowanie obiektowe

Poćwicz samodzielnie: Edytor online Kotlin