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
40Un 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
18Dentro 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 changesDesafío
FácilCompleta 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)
}
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