Menu
Coddy logo textTech

Acessores Personalizados

Parte da seção Programação Orientada a Objetos do Journey de Kotlin da Coddy. Lição 7 de 57.

Toda propriedade do Kotlin tem um getter, e toda var também tem um setter. Por padrão, eles leem e escrevem um valor armazenado. Em vez disso, um getter personalizado calcula o valor a cada leitura:

class Rectangle(var width: Int, var height: Int) {
    val area: Int
        get() = width * height
}

Dentro de main:

val r = Rectangle(3, 4)
println(r.area)
r.width = 10
println(r.area)

Saída:

12
40

Um setter personalizado executa código sempre que a propriedade recebe um valor. Dentro dele, value é o valor atribuído e field é o valor armazenado por trás da propriedade, o campo de apoio:

class Thermostat {
    var target = 20
        set(value) {
            field = value.coerceIn(10, 30)
        }
}

Dentro de main:

val t = Thermostat()
t.target = 42
println(t.target)
t.target = 18
println(t.target)

Saída:

30
18

Dentro de um acessor, use field, não o nome da propriedade: escrever target = value dentro do setter de target chamaria o setter novamente, para sempre:

var target = 20
    set(value) {
        // target = value        // chama este setter novamente: recursão infinita
        field = value             // armazena o valor
    }

Um setter também é o lugar para reagir a mudanças, por exemplo, para contá-las ou registrá-las:

class Player(name: String) {
    var changes = 0
        private set
    var name = name
        set(value) {
            field = value.trim()
            changes++
        }
}

Dentro de main:

val p = Player("ada")
p.name = "  Ada  "
p.name = "Ada L."
println("${p.name} after ${p.changes} changes")

Saída:

Ada L. after 2 changes
challenge icon

Desafio

Fácil

Complete a classe Circle(radius: Double). radius é uma var cujo setter armazena valores negativos como 0. Adicione as propriedades somente leitura diameter e area (π r² com Math.PI) com getters personalizados, e label, que retorna r=2.0 d=4.0 a=12.57 com a área arredondada para duas casas decimais ("%.2f".format(area)).

O código fornecido lê um raio por linha, imprime label, depois dobra o raio do último círculo e imprime label novamente; portanto, os valores devem acompanhar o raio.

Seu código deve ficar em Circle.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()
    var last = Circle(0.0)
    for (line in input) {
        last = Circle(line.toDouble())
        println(last.label)
    }
    last.radius *= 2
    println(last.label)
}
quiz iconTeste seus conhecimentos

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

Pratique por conta própria: Playground de Kotlin