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
40Niestandardowy 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
18Wewną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 changesWyzwanie
ŁatwyUzupeł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)
}
Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.
Wszystkie lekcje w sekcji Programowanie obiektowe
1Klasy i obiekty
Praca z plikamiDefiniowanie klasKonstruktory główneBloki init i walidacjaKonstruktory dodatkowePodsumowanie — karta biblioteczna4Dziedziczenie
Klasy otwarte i podklasyNadpisywanie składowychsuper i konstruktoryKlasy abstrakcyjnePodsumowanie – katalog pracowników7Klasy specjalne
Klasy danychKlasy wyliczenioweHierarchie zapieczętowaneequals, hashCode, toStringPodsumowanie — śledzenie zamówień10Wzorce projektowe, część 2
Delegowanie za pomocą byWzorzec dekoratoraWzorzec budowniczegoWzorzec stanu2Właściwości i hermetyzacja
Własne akcesoryModyfikatory widocznościPrywatne setterylazy i lateinitPowtórka – konto bankowe5Interfejsy
Deklarowanie interfejsówMetody domyślneWiele interfejsówInterfejsy jako typyPowtórzenie – metody płatności8Typy generyczne
Funkcje generyczneKlasy generyczneOgraniczenia typówKowariancja i kontrawariancja: in i outPodsumowanie — kolejka priorytetowa11Projekt: Zarządzanie biblioteką
Książki i czytelnicyWypożyczanie książekPoćwicz samodzielnie: Edytor online Kotlin