Menu
Coddy logo textTech

Déclarer des interfaces

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

Une interface répertorie ce qu’un type peut faire sans indiquer comment. Elle déclare les méthodes et les propriétés que chaque classe qui l’implémente doit fournir. Une classe implémente une interface avec deux-points, comme avec une superclasse, mais sans parenthèses, car une interface n’a pas de constructeur :

interface Drawable {
    fun draw(): String
}
class Circle(val radius: Int) : Drawable {
    override fun draw() = "circle with radius $radius"
}
class Line(val length: Int) : Drawable {
    override fun draw() = "-".repeat(length)
}

Dans main :

println(Circle(3).draw())
println(Line(5).draw())

Sortie :

circle with radius 3
-----

Une interface peut également déclarer des propriétés. La classe les fournit sous forme de propriétés du constructeur, de propriétés stockées ou de getters  l’interface elle-même ne stocke rien :

interface Vehicle {
    val wheels: Int
    val label: String
}
class Car(override val label: String) : Vehicle {
    override val wheels = 4
}
class Bike : Vehicle {
    override val wheels = 2
    override val label: String
        get() = "bike on $wheels wheels"
}

Dans main :

println("${Car("taxi").label}: ${Car("taxi").wheels}")
println(Bike().label)

Sortie :

taxi: 4
bike on 2 wheels

Chaque membre déclaré par l’interface doit être implémenté, chacun avec override, sinon la classe ne compile pas. Une interface ne peut pas être instanciée :

interface Speaker {
    fun speak(): String
    val volume: Int
}
// class Mute : Speaker { override fun speak() = "" }   // erreur : volume n'est pas implémenté
// class Loud : Speaker() { ... }                      // erreur : une interface n'a pas de constructeur
// val s = Speaker()                                   // erreur : impossible de créer une interface

Une interface et une classe abstraite déclarent toutes deux des membres sans corps. Une interface n’a ni constructeur ni état stocké, et une classe peut implémenter plusieurs interfaces, mais n’étendre qu’une seule classe. Utilisez une interface pour une capacité que partagent des classes sans lien, comme Drawable ou Comparable, et une classe abstraite pour une base commune avec un état.

interface Drawable { fun draw(): String }                   // une capacité
abstract class Shape(val name: String) { abstract fun area(): Double }   // une base avec état
class Square(val s: Double) : Shape("square"), Drawable {  // une classe, n'importe quelles interfaces
    override fun area() = s * s
    override fun draw() = "[]"
}
challenge icon

Défi

Facile

Déclarez les membres de l’interface Shape : une propriété en lecture seule name et les méthodes area() et perimeter(), renvoyant toutes deux Double. Faites en sorte que Rectangle(width, height) (nom rectangle) et Circle(radius) (nom circle, utilisant Math.PI) les implémentent. Complétez ensuite describe(shape), qui renvoie rectangle: area 12.00, perimeter 14.00 avec deux décimales, en utilisant uniquement les membres de Shape.

Le code fourni lit des lignes r,3,4 ou c,2, crée la forme correspondante et affiche describe(shape).

Votre code doit se trouver dans Shape.kt, Rectangle.kt, Circle.kt et Functions.kt. Main.kt contient le code fourni d’entrée et de sortie 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()
    for (line in input) {
        val p = line.split(",").map { it.trim() }
        val shape: Shape = if (p[0] == "r") Rectangle(p[1].toDouble(), p[2].toDouble()) else Circle(p[1].toDouble())
        println(describe(shape))
    }
}
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