Menu
Coddy logo textTech

Metodi predefiniti

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

Un metodo di un'interfaccia può avere un corpo. Questa implementazione predefinita viene usata da ogni classe che non la sovrascrive:

interface Greeter {
    val name: String
    fun greet() = "Hello, I am $name"
}
class Robot(override val name: String) : Greeter
class Pirate(override val name: String) : Greeter {
    override fun greet() = "Ahoy! $name here"
}

Dentro main:

println(Robot("R2").greet())
println(Pirate("Anne").greet())

Output:

Hello, I am R2
Ahoy! Anne here

I metodi predefiniti sono scritti in termini degli altri membri dell’interfaccia. Una classe fornisce i pochi membri che differiscono e riceve gli altri:

interface Priced {
    val cents: Int
    fun formatted() = "$%d.%02d".format(cents / 100, cents % 100)
    fun isAffordable(budget: Int) = cents <= budget
}
class Coffee : Priced {
    override val cents = 450
}

All’interno di main:

val c = Coffee()
println(c.formatted())
println(c.isAffordable(400))

Output:

$4.50
false

Le proprietà possono avere un getter predefinito, ma un'interfaccia non ha campi di supporto, quindi non può memorizzare un valore. Una proprietà con un inizializzatore non viene compilata; un getter che calcola il valore, invece, sì:

interface Box {
    val width: Int
    val height: Int
    val area: Int
        get() = width * height
    // val count = 0      // errore: gli inizializzatori delle proprietà non sono consentiti nelle interfacce
}
class Tile(override val width: Int, override val height: Int) : Box

All'interno di main:

println(Tile(3, 4).area)

Output:

12

Una ridefinizione può comunque usare l'implementazione predefinita. All'interno della classe, super.method() chiama la versione dell'interfaccia:

interface Priced {
    val cents: Int
    fun formatted() = "$%d.%02d".format(cents / 100, cents % 100)
}
class Coffee : Priced {
    override val cents = 450
    override fun formatted() = "coffee " + super.formatted()
}

All'interno di main:

println(Coffee().formatted())

Output:

coffee $4.50
challenge icon

Sfida

Facile

L'interfaccia Priced ha price (in centesimi). Forniscile un metodo predefinito formatted() che restituisca $4.50 e un metodo predefinito isAffordable(budget) che restituisca se il prezzo è al massimo pari al budget. Coffee costa 450 e sostituisce formatted() con coffee $4.50, riutilizzando il metodo predefinito tramite super. Sandwich(price) usa entrambi i metodi predefiniti.

Il codice fornito legge un budget in centesimi e poi righe coffee oppure sandwich,650. Stampa formatted() e yes oppure no per ogni elemento.

Il tuo codice va inserito in Priced.kt, Coffee.kt e Sandwich.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()
    val budget = input[0].toInt()
    for (line in input.drop(1)) {
        val p = line.split(",")
        val item: Priced = if (p[0] == "coffee") Coffee() else Sandwich(p[1].toInt())
        println("${item.formatted()} ${if (item.isAffordable(budget)) "yes" else "no"}")
    }
}
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