Extension function en Kotlin : définition, syntaxe et application

Auteur : IT Sectr Publié le : 2026-06-21 Temps de lecture : 9 min

extension function — un mécanisme Kotlin qui permet d'ajouter de nouvelles méthodes aux classes existantes sans héritage et sans modifier le code source. La fonction est déclarée avec un préfixe sous la forme d'un type récepteur et est appelée comme une méthode normale de ce type. Selon Kotlin Documentation, 2025, les extension functions sont compilées en méthodes statiques avec le récepteur comme premier paramètre, ce qui garantit zéro surcharge à l'exécution par rapport aux appels normaux.

Points clés

  • Extension function — une méthode avec un type récepteur, appelée comme membre de la classe sans héritage
  • Type récepteur est spécifié par un point avant le nom de la fonction : fun Type.method()
  • Dispatch statique — l'extension function n'est pas virtuelle, elle est appelée selon le type de la variable
  • Import obligatoire : les extension functions ne sont pas des membres de la classe et nécessitent un import
  • Les membres de classe ont priorité : si la méthode correspond, le membre de classe est appelé, pas l'extension

Qu'est-ce qu'une extension function en Kotlin ?

Une extension function est une fonction déclarée en dehors d'une classe mais appelée comme sa méthode. Elle prend un type récepteur auquel la nouvelle méthode est ajoutée. À l'intérieur de la fonction, le mot-clé this fait référence à l'instance du type récepteur. Cette approche permet d'étendre les classes finales, les classes de bibliothèques tierces et même les types primitifs sans créer de wrappers.

Contrairement à Java, où ajouter une méthode à une classe existante nécessite soit l'héritage, soit une classe utilitaire statique, Kotlin offre une solution élégante sans boilerplate. Selon une étude de la Kotlin Foundation (2024), les extension functions font partie des cinq fonctionnalités les plus utilisées du langage — 78 % des développeurs Kotlin les utilisent dans leur travail quotidien.

Le compilateur Kotlin traduit une extension function en une méthode statique où l'instance du récepteur est passée comme premier argument. Cela signifie que les extension functions ne modifient pas le bytecode de la classe cible et ne brisent pas l'encapsulation — seuls les champs et méthodes publics du récepteur sont accessibles.

Utilisez les extension functions pour écrire des fonctions utilitaires propres qui sont logiquement liées à un type spécifique mais ne peuvent pas être ajoutées à son code source.

Syntaxe de l'extension function : déclaration et appel

La syntaxe de base d'une extension function : le nom du type récepteur, un point, le nom de la fonction, puis les paramètres et le type de retour. À l'intérieur de la fonction, le récepteur est accessible via this.

kotlin
// Extension function for String
fun String.isEmail(): Boolean {
    return this.contains("@") && this.contains(".")
}

// Called as regular String method
val result = "user@example.com".isEmail() // true

Dans cet exemple, isEmail() devient disponible pour toutes les chaînes. À l'intérieur de la fonction, this fait référence à la chaîne elle-même sur laquelle la méthode est appelée. Kotlin permet d'omettre this dans la plupart des cas — on peut simplement écrire contains("@") au lieu de this.contains("@").

Extension function avec paramètres

Les extension functions peuvent accepter des paramètres supplémentaires et retourner des valeurs de n'importe quel type. Cela en fait des fonctions à part entière, pas seulement du sucre syntaxique.

kotlin
fun List<Int>.defaultIfEmpty(default: Int): List<Int> {
    if (this.isEmpty()) return listOf(default)
    return this
}

val populated = listOf(1, 2).defaultIfEmpty(0)
val empty = listOf<Int>().defaultIfEmpty(0)

Le paramètre default définit la valeur retournée pour une liste vide. Une extension function peut être générique — le type List est générique, bien que l'exemple utilise un List spécifique.

Dispatch statique et récepteur

Les extension functions en Kotlin utilisent le dispatch statique, pas le dispatch virtuel. C'est une différence clé par rapport aux méthodes de classe normales. Quelle extension function est appelée est déterminée à la compilation par le type statique de la variable, pas par son type réel à l'exécution.

kotlin
open class Animal
class Dog : Animal()

fun Animal.speak() = "Animal sound"
fun Dog.speak() = "Woof"

fun test() {
    val animal: Animal = Dog()
    println(animal.speak()) // "Animal sound" — static type Animal

    val dog: Dog = Dog()
    println(dog.speak()) // "Woof" — static type Dog
}

Même si la variable animal pointe vers une instance de Dog, l'extension function pour Animal est appelée car le type statique de la variable est Animal. Si speak() était une méthode virtuelle de classe, Dog.speak() aurait été appelée. Ce comportement est important à prendre en compte lors de la conception d'API avec des extension functions.

Import et portée des extension functions

Les extension functions ne sont pas des membres de classe — ce sont des fonctions normales qui nécessitent un import pour être utilisées dans un autre fichier. Kotlin propose deux options d'import : par nom de fonction ou avec renommage.

kotlin
// Import by name
import com.example.extensions.isEmail

// Import with alias (to resolve conflicts)
import com.example.extensions.isEmail as isValidEmail

// Call after import
val valid = "test@test.com".isEmail()

Le renommage via as est utile pour les conflits de noms — par exemple, si deux bibliothèques fournissent une extension function avec le même nom pour le même type. Dans ce cas, vous pouvez importer l'une d'elles avec un nom différent et l'appeler en utilisant le nouveau nom.

Portée

Les extension functions peuvent être déclarées à différents niveaux :

NiveauVisibilitéExemple
Top-levelProjet entier après importfun String.isEmail()
Member extensionÀ l'intérieur de la classe propriétaireclass A { fun B.ext() }
LocalÀ l'intérieur d'une fonctionfun test() { fun String.ext() }

Les member extension functions sont un cas particulier où une extension function est déclarée à l'intérieur d'une autre classe. Dans ce cas, à la fois le récepteur (this de la fonction) et les membres de la classe externe sont accessibles à l'intérieur de l'extension function.

Priorité des membres de classe sur les extensions

Si une classe a une méthode avec la même signature qu'une extension function, le membre de classe est toujours appelé. Une extension function ne remplace jamais une méthode de classe — c'est une décision architecturale pour éviter les remplacements accidentels.

kotlin
class User {
    fun greet() = "Hello from class"
}

fun User.greet() = "Hello from extension"

fun main() {
    val user = User()
    println(user.greet()) // "Hello from class"
}

Même si l'extension function est définie plus tard et a la même signature, le compilateur choisira la méthode de classe. Le compilateur Kotlin émet un avertissement lorsqu'il détecte cette situation. La seule façon d'appeler l'extension function lorsqu'une méthode de classe existe est de l'invoquer comme une fonction normale : greet(user).

Exemples pratiques d'extension functions

Dans le développement Android, les extension functions sont devenues un outil standard pour travailler avec View, Context et les fragments. La bibliothèque Android KTX est construite sur des extension functions, fournissant des wrappers pratiques sur l'API Android.

kotlin
// Extension function for working with View
fun View.show() {
    visibility = View.VISIBLE
}

fun View.hide() {
    visibility = View.GONE
}

// Extension function for Context — toast
fun Context.toast(message: String) {
    Toast.makeText(this, message, Toast.LENGTH_SHORT).show()
}

// Extension function as DSL builder
fun String.colorFormat(color: String): String =
    "$color$this\u001b[0m"

L'extension function toast() rend les appels dépendants de Context concis : au lieu d'écrire Toast.makeText(context, message, length).show(), il suffit d'écrire context.toast("Texte"). Cela réduit le boilerplate et rend le code plus lisible.

Foire aux questions

Peut-on redéfinir une extension function dans une sous-classe ?

Non, les extension functions utilisent le dispatch statique. Si vous déclarez une extension function pour une classe de base et la même pour une sous-classe, laquelle sera appelée est déterminée par le type statique de la variable à la compilation, pas par le type réel à l'exécution.

Comment les extension functions fonctionnent-elles avec les types nullables ?

Vous pouvez déclarer des extension functions pour des types récepteurs nullables : fun String?.isNullOrEmail(). À l'intérieur d'une telle fonction, this peut être null, vous devez donc utiliser des opérateurs d'appel sécurisé ou des vérifications explicites de null.

Les extension functions ont-elles une surcharge de performance ?

Non, les extension functions sont compilées en méthodes statiques. Au niveau du bytecode, appeler une extension function est identique à appeler une méthode statique avec le récepteur comme premier paramètre. Aucune réflexion ni dispatch dynamique n'est impliqué.

Peut-on déclarer une extension property pour une classe ?

Oui, les extension properties fonctionnent de manière similaire aux extension functions mais ne peuvent pas stocker d'état — seulement un getter et un setter. Par exemple : val List.sum get() = reduce(Int::plus). Elles sont également compilées en méthodes getter/setter statiques.

En quoi les extension functions diffèrent-elles des méthodes dans les classes utilitaires Java ?

En Java on écrit StringUtils.isEmail(str), alors qu'en Kotlin on écrit str.isEmail(). La différence n'est pas seulement syntaxique : les extension functions supportent l'autocomplétion dans l'IDE, améliorent la lisibilité des chaînes d'appels et permettent à l'IDE de suggérer des fonctions pertinentes pour un type spécifique. Java ne dispose pas de ces capacités.

Résumé

  • Extension function — une méthode avec un type récepteur, appelée comme membre de la classe sans héritage
  • Dispatch statique — sélection de fonction par type statique, pas par type d'exécution
  • Zéro surcharge — compilée en méthode statique avec le récepteur comme premier paramètre
  • Import obligatoire pour utilisation dans d'autres fichiers, alias via as supporté
  • Les membres de classe ont priorité sur les extension functions avec la même signature
  • Member extensions — extensions déclarées à l'intérieur d'une classe ont accès à ses membres
  • Utilisation pratique — utilitaires pour String, View, Context, collections et construction DSL

Nous développerons une application mobile clé en main

IT Sectr crée des applications iOS et Android pour les startups et les entreprises depuis 2017. Nous vous conseillerons et vous proposerons la meilleure solution.

Discuter du projet

Lisez aussi