En Kotlin, le mot-clé super est utilisé pour faire référence à l'implémentation d'une méthode ou d'une propriété de la superclasse ou de l'interface implémentée. Contrairement à Java, Kotlin permet de spécifier explicitement par quelle interface ou classe appeler l'implémentation de la méthode, ce qui est particulièrement important lors du "conflit" de plusieurs interfaces avec les mêmes méthodes.
Particularité : Si une classe implémente plusieurs interfaces qui définissent une méthode avec la même signature et qu'une implémentation par défaut est présente, il est nécessaire d'indiquer explicitement quelle implémentation utiliser.
Exemple :
interface A { fun foo() = println("A") } interface B { fun foo() = println("B") } class C : A, B { override fun foo() { super<A>.foo() // Appel explicite à A.foo super<B>.foo() // Appel explicite à B.foo } }
Cela n'est pas directement pris en charge en Java (Java ne permet pas aux interfaces d'avoir des champs/implémentations de méthodes jusqu'à Java 8, et même dans Java 8 - les mécanismes sont différents).
"Peut-on en Kotlin faire appel à l'implémentation d'une méthode de la superclasse à travers plusieurs niveaux d'héritage ?"
super<Intermediate>.foo(), mais ce n'est pas le cas - on peut appeler uniquement la superclasse immédiate ou l'interface qui implémente cette méthode directement.Exemple :
open class Base { open fun foo() = println("Base") } open class Mid : Base() { override fun foo() { println("Mid"); super.foo() } } class Child: Mid() { override fun foo() { super.foo() // appellera Mid.foo() // super<Base>.foo() — erreur de compilation } }
Histoire
Dans un grand projet, les interfaces
LoggeretAuditordéfinissaient toutes deux la méthoderecord(). Lors de l'implémentation d'une classe héritant des deux interfaces, le programmeur n'a pas redéfini explicitementrecord(), ce qui a entraîné une erreur de compilation "La classe doit redéfinir la fonction publique ouverte record()". Il a fallu implémenter la méthode manuellement et déléguer explicitement à l'interface correspondante.
Histoire
En essayant d'appeler l'implémentation de la méthode de la superclasse à travers plusieurs couches intermédiaires (par exemple,
super<Base>.foo()), une erreur de compilation est survenue. Le développeur ne connaissait pas les limitations de Kotlin et ne comprenait pas pourquoi l'appel direct était impossible.
Histoire
Après la mise à jour de l'API, l'une des interfaces a ajouté une implémentation de fonction par défaut, qui coïncidait avec une autre interface. L'ancien code ne compilait plus en raison d'un conflit d'implémentations - il a fallu résoudre explicitement le conflit en implémentant la méthode soi-même et en choisissant quelles implémentations de superinterfaces appeler à l'intérieur.