Blocos init e Validação
Parte da seção Programação Orientada a Objetos do Journey de Kotlin da Coddy. Lição 4 de 57.
Um bloco init é executado quando uma instância é criada, logo após os parâmetros do construtor serem atribuídos. Ele é o lugar para o código de configuração que não cabe em uma única declaração de propriedade:
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}")Saída:
created order 7
3 items, total 20require(condition) { message } verifica um argumento e lança IllegalArgumentException com a mensagem quando ele é falso. Colocá-lo em init significa que uma instância inválida nunca pode ser criada:
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)
}Saída:
42
percentage must be 0-100, was 150Uma classe pode ter vários blocos init; eles são executados em ordem, juntamente com os inicializadores de propriedades, de cima para baixo:
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")Saída:
first: x
init 1
second
init 2
doneA validação em init mantém a regra próxima dos dados. O código que recebe uma instância pode confiar nela sem verificá-la novamente:
class Email(val address: String) {
init {
require("@" in address) { "not an email: $address" }
}
}
fun send(to: Email) { /* não precisa verificar o endereço novamente */ }Desafio
FácilComplete a classe Password. Seu bloco init verifica, com require, se o texto tem pelo menos 8 caracteres (mensagem too short) e contém um dígito (mensagem needs a digit), nessa ordem. A propriedade strength é calculada em init: strong quando o texto também contém uma letra maiúscula; caso contrário, ok.
O código fornecido cria um Password para cada linha de entrada e imprime strength ou a mensagem de erro.
Seu código deve ser colocado em Password.kt. Main.kt contém o código fornecido de entrada/saída e não pode ser editado.
Experimente você mesmo
fun main() {
// Código de entrada/saída fornecido: mantenha-o como está
val input = generateSequence(::readLine).toList()
for (line in input) {
try {
println(Password(line).strength)
} catch (e: IllegalArgumentException) {
println(e.message)
}
}
}
Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.
Todas as lições de Programação Orientada a Objetos
1Classes e Objetos
Trabalhando com ArquivosDefinindo ClassesConstrutores PrimáriosBlocos init e ValidaçãoConstrutores SecundáriosRecapitulação - Cartão da Biblioteca4Herança
Classes Abertas e SubclassesSobrescrevendo Membrossuper e ConstrutoresClasses AbstratasRevisão - Diretório de Funcionários2Propriedades e Encapsulamento
Acessores PersonalizadosModificadores de VisibilidadeSetters Privadoslazy e lateinitRevisão - Conta Bancária5Interfaces
Declarando InterfacesMétodos PadrãoMúltiplas InterfacesInterfaces como TiposRecapitulação - Métodos de Pagamento8Genéricos
Funções genéricasClasses genéricasRestrições de tipoVariância com in e outRecapitulação - Fila de prioridade11Projeto: Gerenciamento de Biblioteca
Livros e MembrosEmpréstimo de LivrosPratique por conta própria: Playground de Kotlin