Blocchi init e convalida
Fa parte della sezione Programmazione orientata agli oggetti del percorso Kotlin di Coddy. Lezione 4 di 57.
Un blocco init viene eseguito quando viene creata un'istanza, subito dopo l'assegnazione dei parametri del costruttore. È il posto in cui inserire il codice di inizializzazione che non trova spazio in una singola dichiarazione di proprietà:
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")
}
}All'interno di main:
val o = Order(7, listOf(4, 6, 10))
println("${o.count} items, total ${o.total}")Output:
created order 7
3 items, total 20require(condition) { message } controlla un argomento e genera IllegalArgumentException con il messaggio quando è falso. Inserirlo in init significa che non è mai possibile creare un'istanza non valida:
class Percentage(val value: Int) {
init {
require(value in 0..100) { "percentage must be 0-100, was $value" }
}
}Dentro main:
println(Percentage(42).value)
try {
Percentage(150)
} catch (e: IllegalArgumentException) {
println(e.message)
}Output:
42
percentage must be 0-100, was 150Una classe può avere diversi blocchi init; vengono eseguiti in ordine, insieme agli inizializzatori delle proprietà, dall'alto verso il basso:
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") }
}All'interno di main:
Demo("x")
println("done")Output:
first: x
init 1
second
init 2
doneLa convalida in init mantiene la regola accanto ai dati. Il codice che riceve un'istanza può fidarsi di essa senza controllarla di nuovo:
class Email(val address: String) {
init {
require("@" in address) { "not an email: $address" }
}
}
fun send(to: Email) { /* non è necessario controllare di nuovo l'indirizzo */ }Sfida
FacileCompleta la classe Password. Il suo blocco init verifica, con require, che il testo abbia almeno 8 caratteri (messaggio too short) e contenga una cifra (messaggio needs a digit), in quest’ordine. La proprietà strength viene calcolata in init: strong quando il testo contiene anche una lettera maiuscola, altrimenti ok.
Il codice fornito crea un Password per ogni riga di input e stampa strength oppure il messaggio di errore.
Il tuo codice va in Password.kt. Main.kt contiene il codice di input/output fornito e non può essere modificato.
Provalo tu
fun main() {
// Codice di input/output fornito: lascialo così com'è
val input = generateSequence(::readLine).toList()
for (line in input) {
try {
println(Password(line).strength)
} catch (e: IllegalArgumentException) {
println(e.message)
}
}
}
Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.
Tutte le lezioni di Programmazione orientata agli oggetti
1Classi e oggetti
Lavorare con i fileDefinire le classiCostruttori primariBlocchi init e convalidaCostruttori secondariRiepilogo - Tessera della biblioteca4Ereditarietà
Classi aperte e sottoclassiRidefinizione dei membrisuper e costruttoriClassi astratteRiepilogo - Elenco del personale2Proprietà e incapsulamento
Accessor personalizzatiModificatori di visibilitàSetter privatilazy e lateinitRipasso - Conto bancario5Interfacce
Dichiarare le interfacceMetodi predefinitiInterfacce multipleLe interfacce come tipiRiepilogo - Metodi di pagamento8Tipi generici
Funzioni genericheClassi genericheVincoli sui tipiVarianza con in e outRiepilogo - Coda con priorità11Progetto: Gestione della biblioteca
Libri e sociPrendere in prestito i libriEsercitati da solo: Playground Kotlin