Menu
Coddy logo textTech

Méthodes par défaut

Fait partie de la section Programmation orientée objet du Journey Kotlin de Coddy. Leçon 23 sur 57.

Une méthode d’interface peut avoir un corps. Cette implémentation par défaut est utilisée par chaque classe qui ne la redéfinit pas :

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"
}

À l’intérieur de main :

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

Sortie :

Hello, I am R2
Ahoy! Anne here

Les méthodes par défaut sont écrites en fonction des autres membres de l’interface. Une classe fournit les quelques membres qui diffèrent et reçoit le reste :

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
}

À l’intérieur de main :

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

Sortie :

$4.50
false

Les propriétés peuvent avoir un accesseur par défaut, mais une interface n’a pas de champs de stockage et ne peut donc pas stocker de valeur. Une propriété avec un initialiseur ne compile pas ; en revanche, un accesseur qui calcule la valeur fonctionne :

interface Box {
    val width: Int
    val height: Int
    val area: Int
        get() = width * height
    // val count = 0      // erreur : les initialisateurs de propriétés ne sont pas autorisés dans les interfaces
}
class Tile(override val width: Int, override val height: Int) : Box

À l’intérieur de main :

println(Tile(3, 4).area)

Sortie :

12

Une redéfinition peut tout de même utiliser l’implémentation par défaut. À l’intérieur de la classe, super.method() appelle la version de l’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()
}

À l’intérieur de main :

println(Coffee().formatted())

Sortie :

coffee $4.50
challenge icon

Défi

Facile

L’interface Priced possède price (en centimes). Donnez-lui un formatted() par défaut qui renvoie $4.50 et un isAffordable(budget) par défaut qui indique si le prix est inférieur ou égal au budget. Coffee coûte 450 et remplace formatted() par coffee $4.50, en réutilisant la valeur par défaut via super. Sandwich(price) utilise les deux valeurs par défaut.

Le code fourni lit un budget en centimes, puis des lignes coffee ou sandwich,650. Il affiche formatted() ainsi que yes ou no pour chaque élément.

Votre code doit se trouver dans Priced.kt, Coffee.kt et Sandwich.kt. Main.kt contient le code fourni pour les entrées et les sorties et ne peut pas être modifié.

Essayez vous-même

fun main() {
    // Code d'entrée/sortie fourni : le garder tel quel
    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 iconTestez-vous

Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.

Toutes les leçons de Programmation orientée objet

Entraînez-vous par vous-même : Playground Kotlin