Menu
Coddy logo textTech

Accesores personalizados

Parte de la sección Programación orientada a objetos del Journey de Kotlin de Coddy. Lección 7 de 57.

Cada propiedad de Kotlin tiene un getter, y cada var también tiene un setter. De forma predeterminada, leen y escriben un valor almacenado. En cambio, un getter personalizado calcula el valor en cada lectura:

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)

Salida:

12
40

Un setter personalizado ejecuta código cada vez que se asigna la propiedad. Dentro de él, value es el valor asignado y field es el valor almacenado detrás de la propiedad, el campo de respaldo:

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)

Salida:

30
18

Dentro de un accesor, usa field, no el nombre de la propiedad: escribir target = value dentro del setter de target volvería a llamar al setter, para siempre:

var target = 20
    set(value) {
        // target = value        // llama a este setter de nuevo: recursión infinita
        field = value             // almacena el valor
    }

Un setter también es el lugar para reaccionar a los cambios, por ejemplo, para contarlos o registrarlos:

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")

Salida:

Ada L. after 2 changes
challenge icon

Desafío

Fácil

Completa la clase Circle(radius: Double). radius es un var cuyo setter almacena los valores negativos como 0. Añade las propiedades de solo lectura diameter y area (π r² con Math.PI) con getters personalizados, y label, que devuelve r=2.0 d=4.0 a=12.57 con el área redondeada a dos decimales ("%.2f".format(area)).

El código proporcionado lee un radio por línea, imprime label, después duplica el radio del último círculo e imprime label de nuevo, por lo que los valores deben seguir al radio.

Tu código va en Circle.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()
    var last = Circle(0.0)
    for (line in input) {
        last = Circle(line.toDouble())
        println(last.label)
    }
    last.radius *= 2
    println(last.label)
}
quiz iconPonte a prueba

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

Practica por tu cuenta: Playground de Kotlin