Menu
Coddy logo textTech

Métodos predeterminados

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

Un método de una interfaz puede tener un cuerpo. Esta implementación predeterminada es utilizada por toda clase que no la sobrescribe:

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 de main:

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

Salida:

Hello, I am R2
Ahoy! Anne here

Los métodos predeterminados se escriben en términos de los otros miembros de la interfaz. Una clase proporciona los pocos miembros que difieren y recibe el resto:

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
}

Dentro de main:

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

Salida:

$4.50
false

Las propiedades pueden tener un getter predeterminado, pero una interfaz no tiene campos de respaldo, por lo que no puede almacenar un valor. Una propiedad con un inicializador no se compila; un getter que calcula el valor sí:

interface Box {
    val width: Int
    val height: Int
    val area: Int
        get() = width * height
    // val count = 0      // error: los inicializadores de propiedades no están permitidos en interfaces
}
class Tile(override val width: Int, override val height: Int) : Box

Dentro de main:

println(Tile(3, 4).area)

Salida:

12

Una sobrescritura aún puede usar la implementación predeterminada. Dentro de la clase, super.method() llama a la versión de la interfaz:

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()
}

Dentro de main:

println(Coffee().formatted())

Salida:

coffee $4.50
challenge icon

Desafío

Fácil

La interfaz Priced tiene price (en centavos). Dale un formatted() predeterminado que devuelva $4.50 y un isAffordable(budget) predeterminado que devuelva si el precio es como máximo el presupuesto. Coffee cuesta 450 y reemplaza formatted() con coffee $4.50, reutilizando el valor predeterminado mediante super. Sandwich(price) usa ambos valores predeterminados.

El código proporcionado lee un presupuesto en centavos y después líneas coffee o sandwich,650. Imprime formatted() y yes o no para cada elemento.

Tu código va en Priced.kt, Coffee.kt y Sandwich.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()
    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 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