Comment l'héritage et le polymorphisme sont-ils organisés en Kotlin?
sobes.tech IA
Réponse de l'IA
En Kotlin, l'héritage est réalisé via des mécanismes de classes et d'interfaces. Les classes peuvent hériter d'une seule autre classe (héritage simple), mais peuvent implémenter plusieurs interfaces.
Par défaut, toutes les classes en Kotlin sont 'final', c'est-à-dire qu'elles ne peuvent pas être héritées. Pour autoriser l'héritage, une classe doit être explicitement marquée avec le mot-clé open.
Héritage de classes :
open class Shape { // Classe de base, marquée comme open
open fun draw() { // Méthode pouvant être redéfinie
println("Dessiner une forme")
}
}
class Circle : Shape() { // Héritage de Shape
override fun draw() { // Redéfinition de la méthode
println("Dessiner un cercle")
}
}
Dans le constructeur de la classe fille, il est nécessaire d'appeler explicitement ou implicitement le constructeur de la classe de base.
Interfaces :
Les interfaces en Kotlin sont similaires à celles de Java 8 et peuvent contenir des méthodes abstraites et des méthodes avec une implémentation. Les classes peuvent implémenter une ou plusieurs interfaces.
interface Drawable {
fun draw() // Méthode abstraite
fun description() { // Méthode avec une implémentation par défaut
println("Ceci est un objet dessinable")
}
}
class Square : Drawable {
override fun draw() { // Implémentation de la méthode abstraite
println("Dessiner un carré")
}
// description() peut être redéfini, mais ce n'est pas obligatoire
}
Polymorphisme :
Le polymorphisme en Kotlin est réalisé grâce à la capacité de travailler avec des objets de différentes classes via un type de base commun (classe ou interface). Cela permet d'appeler des méthodes spécifiques au type réel de l'objet lors de l'exécution.
fun render(drawable: Drawable) {
drawable.draw() // Appel de la méthode draw() selon le type réel de l'objet
drawable.description()
}
fun main() {
val circle: Shape = Circle() // L'objet Circle est considéré comme Shape
circle.draw() // Appel de draw() de Circle grâce au polymorphisme
val square: Drawable = Square() // L'objet Square est considéré comme Drawable
render(square) // Appel de draw() et description() de Square
}
Dans cet exemple, render fonctionne avec tout objet implémentant Drawable. L'appel à drawable.draw() exécutera l'implémentation de la méthode draw pour le type spécifique de l'objet (Square dans ce cas).
Différences entre héritage de classes et implémentation d'interfaces :
- Héritage de classe : Établit une relation "est un" (is-a). La classe fille hérite de l'état et du comportement de la classe de base.
- Implémentation d'interface : Définit une "capacité" ou un "contrat". La classe promet de fournir l'implémentation de toutes les méthodes abstraites de l'interface.
Tableau comparatif :
| Caractéristique | Héritage de classe | Implémentation d'interface |
|---|---|---|
| Type de relation | est-a | Capacité / Contrat |
| Multiplicité | Unique | Multiple |
| État | Hérite de l'état de la classe de base | N'hérite pas de l'état |
| Implémentation des méthodes | Peut contenir une implémentation | Peut contenir une implémentation par défaut (depuis Java 8) |