Historique de la question :
La redéfinition des méthodes est la base de la POO, mais en Java, 'override' n'était pas obligatoire au départ. Kotlin est un langage strictement typé qui a introduit l'utilisation obligatoire de 'override' pour améliorer la clarté du code et éviter les erreurs accidentelles lors de l'héritage.
Problème :
Sans indiquer explicitement 'override', il est facile de se tromper lors de la description d'une interface/classe : faute de frappe dans le nom, le type, le modificateur. Le programme ne crachera pas, mais la redéfinition attendue ne fonctionnera pas. Kotlin résout ce problème de manière radicale.
Solution :
En Kotlin, pour qu'une méthode puisse être redéfinie, elle doit être déclarée comme 'open' (ou 'abstract/interface'). Il est obligatoire d'écrire 'override' pour redéfinir. Si les signatures ne correspondent pas, une erreur de compilation se produira. Cela prévient la plupart des bugs classiques de Java.
Exemple de code :
open class Base { open fun greet() { println("Hello!") } } class Child : Base() { override fun greet() { println("Hi!") } }
Caractéristiques clés :
Peut-on redéfinir accidentellement une fonction si l'on oublie 'override' ?
Non. Si vous avez omis 'override', la méthode déclarée sera considérée comme une nouvelle méthode de classe, et aucune redéfinition ne se produira — le compilateur générera une erreur si 'open' est présent dans la méthode de base.
Exemple de code :
open class A { open fun test() {} } class B : A() { fun test() {} // ne redéfinit pas ! De même pour test2() }
Les méthodes peuvent-elles avoir une visibilité plus stricte que celle du parent ?
Non. Il n'est pas possible de restreindre la portée de la méthode redéfinie. Par exemple, si la méthode de base est 'public', la redéfinition ne peut pas être 'private/protected/internal'. Le compilateur générera une erreur.
Un composant 'override' peut-il être 'final' ?
Oui ! Si vous ne voulez pas d'autres redéfinitions, ajoutez 'final' :
class D : Base() { final override fun greet() { //... } }
En Java :
public class Parent {void foo(){} } public class Child extends Parent {void foo(int x){} }
Une redéfinition était attendue, mais en réalité, c'est une surcharge. Les appels ne vont pas dans la bonne méthode.
Avantages :
Inconvénients :
En Kotlin :
open class Parent { open fun foo() {} } class Child : Parent() { override fun foo() { /*...*/ } }
Avantages :
Inconvénients :