Menu
Coddy logo textTech

Métodos Padrão

Parte da seção Programação Orientada a Objetos do Journey de Kotlin da Coddy. Lição 23 de 57.

Um método de interface pode ter um corpo. Essa implementação padrão é usada por toda classe que não a substitui:

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

Saída:

Hello, I am R2
Ahoy! Anne here

Métodos padrão são escritos com base nos outros membros da interface. Uma classe fornece os poucos membros que diferem e recebe o restante:

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

Saída:

$4.50
false

As propriedades podem ter um getter padrão, mas uma interface não possui campos de suporte, portanto não pode armazenar um valor. Uma propriedade com um inicializador não compila; um getter que calcula o valor, sim:

interface Box {
    val width: Int
    val height: Int
    val area: Int
        get() = width * height
    // val count = 0      // erro: inicializadores de propriedades não são permitidos em interfaces
}
class Tile(override val width: Int, override val height: Int) : Box

Dentro de main:

println(Tile(3, 4).area)

Saída:

12

Uma sobrescrita ainda pode usar a implementação padrão. Dentro da classe, super.method() chama a versão da interface:

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

Saída:

coffee $4.50
challenge icon

Desafio

Fácil

A interface Priced tem price (em centavos). Dê a ela um formatted() padrão que retorne $4.50 e um isAffordable(budget) padrão que retorne se o preço é no máximo o orçamento. Coffee custa 450 e substitui formatted() por coffee $4.50, reutilizando o padrão por meio de super. Sandwich(price) usa ambos os padrões.

O código fornecido lê um orçamento em centavos e, em seguida, linhas coffee ou sandwich,650. Ele imprime formatted() e yes ou no para cada item.

Seu código deve ficar em Priced.kt, Coffee.kt e Sandwich.kt. Main.kt contém o código fornecido de entrada/saída e não pode ser editado.

Experimente você mesmo

fun main() {
    // Código de entrada/saída fornecido: mantenha-o 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 iconTeste seus conhecimentos

Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.

Todas as lições de Programação Orientada a Objetos

Pratique por conta própria: Playground de Kotlin