Menu
Coddy logo textTech

Accessor personalizzati

Fa parte della sezione Programmazione orientata agli oggetti del percorso Kotlin di Coddy. Lezione 7 di 57.

Ogni proprietà Kotlin ha un getter e ogni var ha anche un setter. Per impostazione predefinita, leggono e scrivono un valore memorizzato. Un getter personalizzato calcola il valore a ogni lettura:

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

All'interno di main:

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

Output:

12
40

Un setter personalizzato esegue codice ogni volta che viene assegnato un valore alla proprietà. Al suo interno, value è il valore assegnato e field è il valore memorizzato dietro la proprietà, il campo di supporto:

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

All'interno di main:

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

Output:

30
18

All'interno di un accessor, usa field, non il nome della proprietà: scrivere target = value all'interno del setter di target richiamerebbe il setter, all'infinito:

var target = 20
    set(value) {
        // target = value        // chiama di nuovo questo setter: ricorsione infinita
        field = value             // memorizza il valore
    }

Un setter è anche il luogo in cui reagire alle modifiche, ad esempio per contarle o registrarle:

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

All'interno di main:

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

Output:

Ada L. after 2 changes
challenge icon

Sfida

Facile

Completa la classe Circle(radius: Double). radius è una var il cui setter memorizza i valori negativi come 0. Aggiungi le proprietà di sola lettura diameter e area (π r² con Math.PI) con getter personalizzati, e label, che restituisce r=2.0 d=4.0 a=12.57 con l'area arrotondata a due decimali ("%.2f".format(area)).

Il codice fornito legge un raggio per riga, stampa label, poi raddoppia il raggio dell'ultimo cerchio e stampa di nuovo label, quindi i valori devono seguire il raggio.

Il tuo codice va in Circle.kt. Main.kt contiene il codice di input/output fornito e non può essere modificato.

Provalo tu

fun main() {
    // Codice di input/output fornito: lascialo così com'è
    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 iconMettiti alla prova

Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.

Tutte le lezioni di Programmazione orientata agli oggetti

Esercitati da solo: Playground Kotlin