Bloki init i walidacja
Część sekcji Programowanie obiektowe ścieżki Kotlin w Coddy. Lekcja 4 z 57.
Blok init jest wykonywany podczas tworzenia instancji, zaraz po przypisaniu parametrów konstruktora. To miejsce na kod inicjalizacyjny, który nie mieści się w jednej deklaracji właściwości:
class Order(val id: Int, items: List<Int>) {
val total: Int
val count: Int
init {
total = items.sum()
count = items.size
println("created order $id")
}
}Wewnątrz main:
val o = Order(7, listOf(4, 6, 10))
println("${o.count} items, total ${o.total}")Wynik:
created order 7
3 items, total 20require(condition) { message } sprawdza argument i zgłasza wyjątek IllegalArgumentException z komunikatem, gdy warunek jest fałszywy. Umieszczenie go w init oznacza, że nie można utworzyć nieprawidłowej instancji:
class Percentage(val value: Int) {
init {
require(value in 0..100) { "percentage must be 0-100, was $value" }
}
}Wewnątrz main:
println(Percentage(42).value)
try {
Percentage(150)
} catch (e: IllegalArgumentException) {
println(e.message)
}Wynik:
42
percentage must be 0-100, was 150Klasa może mieć kilka bloków init; są wykonywane po kolei, wraz z inicjalizatorami właściwości, od góry do dołu:
class Demo(name: String) {
val first = "first: $name".also { println(it) }
init { println("init 1") }
val second = "second".also { println(it) }
init { println("init 2") }
}Wewnątrz main:
Demo("x")
println("done")Wynik:
first: x
init 1
second
init 2
doneWalidacja w init umieszcza regułę obok danych. Kod, który otrzymuje instancję, może jej zaufać bez ponownego sprawdzania:
class Email(val address: String) {
init {
require("@" in address) { "not an email: $address" }
}
}
fun send(to: Email) { /* nie trzeba ponownie sprawdzać adresu */ }Wyzwanie
ŁatwyUzupełnij klasę Password. Jej blok init sprawdza za pomocą require, czy tekst ma co najmniej 8 znaków (komunikat too short) i zawiera cyfrę (komunikat needs a digit), właśnie w tej kolejności. Właściwość strength jest obliczana w bloku init: ma wartość strong, gdy tekst zawiera również wielką literę, a w przeciwnym razie ok.
Dostarczony kod tworzy obiekt Password dla każdego wiersza wejściowego i wypisuje strength lub komunikat o błędzie.
Umieść swój kod w pliku Password.kt. Plik 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()
for (line in input) {
try {
println(Password(line).strength)
} catch (e: IllegalArgumentException) {
println(e.message)
}
}
}
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