Bloques init y validación
Parte de la sección Programación orientada a objetos del Journey de Kotlin de Coddy. Lección 4 de 57.
Un bloque init se ejecuta cuando se crea una instancia, justo después de asignar los parámetros del constructor. Es el lugar para colocar código de configuración que no cabe en una sola declaración de propiedad:
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")
}
}Dentro de main:
val o = Order(7, listOf(4, 6, 10))
println("${o.count} items, total ${o.total}")Salida:
created order 7
3 items, total 20require(condition) { message } comprueba un argumento y lanza IllegalArgumentException con el mensaje cuando es falso. Ponerlo en init significa que nunca se puede crear una instancia no válida:
class Percentage(val value: Int) {
init {
require(value in 0..100) { "percentage must be 0-100, was $value" }
}
}Dentro de main:
println(Percentage(42).value)
try {
Percentage(150)
} catch (e: IllegalArgumentException) {
println(e.message)
}Salida:
42
percentage must be 0-100, was 150Una clase puede tener varios bloques init; se ejecutan en orden, junto con los inicializadores de propiedades, de arriba abajo:
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") }
}Dentro de main:
Demo("x")
println("done")Salida:
first: x
init 1
second
init 2
doneLa validación en init mantiene la regla junto a los datos. El código que recibe una instancia puede confiar en ella sin comprobarla de nuevo:
class Email(val address: String) {
init {
require("@" in address) { "not an email: $address" }
}
}
fun send(to: Email) { /* no es necesario comprobar la dirección de nuevo */ }Desafío
FácilCompleta la clase Password. Su bloque init comprueba, mediante require, que el texto tenga al menos 8 caracteres (mensaje too short) y contenga un dígito (mensaje needs a digit), en ese orden. La propiedad strength se calcula en init: strong cuando el texto también contiene una letra mayúscula; en caso contrario, ok.
El código proporcionado crea un Password para cada línea de entrada e imprime strength o el mensaje de error.
Tu código debe ir en Password.kt. Main.kt contiene el código proporcionado de entrada/salida y no se puede editar.
Pruébalo tú mismo
fun main() {
// Código de entrada/salida suministrado: déjalo tal como está
val input = generateSequence(::readLine).toList()
for (line in input) {
try {
println(Password(line).strength)
} catch (e: IllegalArgumentException) {
println(e.message)
}
}
}
Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.
Todas las lecciones de Programación orientada a objetos
1Clases y objetos
Trabajar con archivosDefinir clasesConstructores primariosBloques init y validaciónConstructores secundariosRepaso - Tarjeta de biblioteca4Herencia
Clases abiertas y subclasesSobrescritura de miembrossuper y constructoresClases abstractasRepaso: directorio del personal2Propiedades y encapsulación
Accesores personalizadosModificadores de visibilidadSetters privadoslazy y lateinitRepaso: cuenta bancaria5Interfaces
Declaración de interfacesMétodos predeterminadosInterfaces múltiplesInterfaces como tiposRepaso: métodos de pago8Genéricos
Funciones genéricasClases genéricasRestricciones de tiposVariancia con in y outRepaso - Cola de prioridad11Proyecto: Gestión de biblioteca
Libros y miembrosPréstamo de librosPractica por tu cuenta: Playground de Kotlin