init-Blöcke und Validierung
Teil des Abschnitts Objektorientierte Programmierung der Kotlin-Journey von Coddy. Lektion 4 von 57.
Ein init-Block wird ausgeführt, wenn eine Instanz erstellt wird, direkt nachdem die Konstruktorparameter zugewiesen wurden. Er ist der richtige Ort für Einrichtungscode, der nicht in eine einzelne Eigenschaftsdeklaration passt:
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")
}
}Innerhalb von main:
val o = Order(7, listOf(4, 6, 10))
println("${o.count} items, total ${o.total}")Ausgabe:
created order 7
3 items, total 20require(condition) { message } überprüft ein Argument und löst IllegalArgumentException mit der Nachricht aus, wenn es falsch ist. Wenn man es in init einfügt, kann niemals eine ungültige Instanz erstellt werden:
class Percentage(val value: Int) {
init {
require(value in 0..100) { "percentage must be 0-100, was $value" }
}
}Innerhalb von main:
println(Percentage(42).value)
try {
Percentage(150)
} catch (e: IllegalArgumentException) {
println(e.message)
}Ausgabe:
42
percentage must be 0-100, was 150Eine Klasse kann mehrere init-Blöcke haben; sie werden zusammen mit den Property-Initialisierern von oben nach unten in dieser Reihenfolge ausgeführt:
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") }
}Innerhalb von main:
Demo("x")
println("done")Ausgabe:
first: x
init 1
second
init 2
doneDie Validierung in init hält die Regel direkt bei den Daten. Code, der eine Instanz erhält, kann ihr vertrauen, ohne erneut zu prüfen:
class Email(val address: String) {
init {
require("@" in address) { "not an email: $address" }
}
}
fun send(to: Email) { /* die Adresse muss nicht erneut überprüft werden */ }Aufgabe
EinfachVervollständige die Klasse Password. Ihr init-Block prüft mit require, dass der Text mindestens 8 Zeichen lang ist (Nachricht too short) und eine Ziffer enthält (Nachricht needs a digit), in dieser Reihenfolge. Die Eigenschaft strength wird in init berechnet: strong, wenn der Text außerdem einen Großbuchstaben enthält, andernfalls ok.
Der bereitgestellte Code erstellt für jede Eingabezeile ein Password-Objekt und gibt strength oder die Fehlermeldung aus.
Dein Code gehört in Password.kt. Main.kt enthält den bereitgestellten Eingabe-/Ausgabecode und darf nicht bearbeitet werden.
Probier es selbst
fun main() {
// Gelieferter Ein-/Ausgabecode: belasse ihn wie er ist
val input = generateSequence(::readLine).toList()
for (line in input) {
try {
println(Password(line).strength)
} catch (e: IllegalArgumentException) {
println(e.message)
}
}
}
Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Alle Lektionen in Objektorientierte Programmierung
1Klassen und Objekte
Arbeiten mit DateienKlassen definierenPrimärkonstruktoreninit-Blöcke und ValidierungSekundärkonstruktorenRückblick – Bibliotheksausweis4Vererbung
Offene Klassen und UnterklassenÜberschreiben von Membernsuper und KonstruktorenAbstrakte KlassenRückblick – Mitarbeiterverzeichnis2Eigenschaften und Kapselung
Benutzerdefinierte ZugriffsmethodenSichtbarkeitsmodifikatorenPrivate Setterlazy und lateinitWiederholung – Bankkonto5Schnittstellen
Schnittstellen deklarierenStandardmethodenMehrere SchnittstellenSchnittstellen als TypenRückblick – Zahlungsmethoden8Generics
Generische FunktionenGenerische KlassenTypbeschränkungenVarianz mit in und outRückblick – Prioritätswarteschlange11Projekt: Bibliotheksverwaltung
Bücher und MitgliederBücher ausleihenÜbe selbstständig: Kotlin-Playground