Extension function en Kotlin: qué es, sintaxis y aplicación

Autor: IT Sectr Publicado: 2026-06-21 Tiempo de lectura: 9 min

extension function — un mecanismo de Kotlin que permite añadir nuevos métodos a clases existentes sin herencia y sin modificar el código fuente. La función se declara con un prefijo en forma de tipo receptor y se llama como un método normal de ese tipo. Según Kotlin Documentation, 2025, las extension functions se compilan como métodos estáticos con el receptor como primer parámetro, lo que garantiza cero overhead en tiempo de ejecución en comparación con las llamadas normales.

Puntos clave

  • Extension function — un método con un tipo receptor, llamado como miembro de la clase sin herencia
  • Tipo receptor se especifica mediante un punto antes del nombre de la función: fun Type.method()
  • Despacho estático — la extension function no es virtual, se llama según el tipo de la variable
  • Import obligatorio: las extension functions no son miembros de la clase y requieren importación
  • Miembros de clase tienen prioridad: si el método coincide, se llama al miembro de la clase, no a la extensión

¿Qué es una extension function en Kotlin?

Una extension function es una función declarada fuera de una clase pero llamada como su método. Toma un tipo receptor al que se añade el nuevo método. Dentro de la función, la palabra clave this hace referencia a la instancia del tipo receptor. Este enfoque permite extender clases finales, clases de bibliotecas de terceros e incluso tipos primitivos sin crear envoltorios.

A diferencia de Java, donde para añadir un método a una clase existente se requiere herencia o una clase utilitaria estática, Kotlin ofrece una solución elegante sin boilerplate. Según un estudio de Kotlin Foundation (2024), las extension functions se encuentran entre las cinco características más utilizadas del lenguaje: el 78% de los desarrolladores Kotlin las utilizan en su trabajo diario.

El compilador de Kotlin traduce una extension function a un método estático donde la instancia del receptor se pasa como primer argumento. Esto significa que las extension functions no modifican el bytecode de la clase destino ni rompen la encapsulación — solo son accesibles los campos y métodos públicos del receptor.

Utilice extension functions para escribir funciones utilitarias limpias que estén lógicamente vinculadas a un tipo específico pero que no puedan añadirse a su código fuente.

Sintaxis de extension function: declaración y llamada

La sintaxis básica de una extension function: el nombre del tipo receptor, un punto, el nombre de la función, luego los parámetros y el tipo de retorno. Dentro de la función, el receptor es accesible mediante 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

En este ejemplo, isEmail() está disponible para todas las cadenas. Dentro de la función, this se refiere a la cadena sobre la que se llama el método. Kotlin permite omitir this en la mayoría de los casos — se puede escribir simplemente contains("@") en lugar de this.contains("@").

Extension function con parámetros

Las extension functions pueden aceptar parámetros adicionales y devolver valores de cualquier tipo. Esto las convierte en funciones completas, no solo en azúcar sintáctico.

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)

El parámetro default define el valor devuelto para una lista vacía. Una extension function puede ser genérica — el tipo List es genérico, aunque el ejemplo usa una List específica.

Despacho estático y receptor

Las extension functions en Kotlin utilizan despacho estático, no despacho virtual. Esta es una diferencia clave con los métodos de clase normales. Qué extension function se llama se determina en tiempo de compilación por el tipo estático de la variable, no por su tipo real en tiempo de ejecución.

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
}

Aunque la variable animal apunta a una instancia de Dog, se llama a la extension function para Animal porque el tipo estático de la variable es Animal. Si speak() fuera un método virtual de clase, se habría llamado a Dog.speak(). Este comportamiento es importante tenerlo en cuenta al diseñar API con extension functions.

Importación y ámbito de las extension functions

Las extension functions no son miembros de la clase — son funciones normales que requieren una importación para usarse en otro archivo. Kotlin proporciona dos opciones de importación: por nombre de función o con renombrado.

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()

El renombrado mediante as es útil para conflictos de nombres — por ejemplo, si dos bibliotecas proporcionan una extension function con el mismo nombre para el mismo tipo. En este caso, puede importar una de ellas con un nombre diferente y llamarla usando el nuevo nombre.

Ámbito

Las extension functions pueden declararse en diferentes niveles:

NivelVisibilidadEjemplo
Top-levelTodo el proyecto después de importarfun String.isEmail()
Member extensionDentro de la clase propietariaclass A { fun B.ext() }
LocalDentro de una funciónfun test() { fun String.ext() }

Las member extension functions son un caso especial donde una extension function se declara dentro de otra clase. En este caso, tanto el receptor (this de la función) como los miembros de la clase externa son accesibles dentro de la extension function.

Prioridad de los miembros de clase sobre las extensiones

Si una clase tiene un método con la misma firma que una extension function, siempre se llama al miembro de la clase. Una extension function nunca sobrescribe un método de clase — esta es una decisión arquitectónica para evitar sobrescrituras accidentales.

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"
}

Incluso si la extension function se define más tarde y tiene la misma firma, el compilador elegirá el método de la clase. El compilador de Kotlin emite una advertencia cuando encuentra esta situación. La única forma de llamar a la extension function cuando existe un método de clase es invocarla como una función normal: greet(user).

Ejemplos prácticos de extension functions

En el desarrollo de Android, las extension functions se han convertido en una herramienta estándar para trabajar con View, Context y fragments. La biblioteca Android KTX está construida sobre extension functions, proporcionando envoltorios convenientes sobre la API de 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"

La extension function toast() hace que las llamadas dependientes de Context sean concisas: en lugar de escribir Toast.makeText(context, message, length).show(), basta con escribir context.toast("Texto"). Esto reduce el boilerplate y hace el código más legible.

Preguntas frecuentes

¿Se puede sobrescribir una extension function en una subclase?

No, las extension functions utilizan despacho estático. Si declara una extension function para una clase base y la misma para una subclase, cuál se llama se determina por el tipo estático de la variable en tiempo de compilación, no por el tipo real en tiempo de ejecución.

¿Cómo funcionan las extension functions con tipos nullable?

Puede declarar extension functions para tipos receptores nullable: fun String?.isNullOrEmail(). Dentro de esta función, this puede ser null, por lo que debe usar operadores de llamada segura o comprobaciones explícitas de null.

¿Tienen las extension functions overhead de rendimiento?

No, las extension functions se compilan como métodos estáticos. A nivel de bytecode, llamar a una extension function es idéntico a llamar a un método estático con el receptor como primer parámetro. No implica reflexión ni despacho dinámico.

¿Se puede declarar una extension property para una clase?

, las extension properties funcionan de manera similar a las extension functions pero no pueden almacenar estado — solo un getter y un setter. Por ejemplo: val List.sum get() = reduce(Int::plus). También se compilan como métodos getter/setter estáticos.

¿En qué se diferencian las extension functions de los métodos en clases utilitarias de Java?

En Java se escribe StringUtils.isEmail(str), mientras que en Kotlin se escribe str.isEmail(). La diferencia no es solo sintáctica: las extension functions soportan autocompletado en IDE, mejoran la legibilidad de las cadenas de llamadas y permiten que el IDE sugiera funciones relevantes para un tipo específico. Java no tiene estas capacidades.

Resumen

  • Extension function — un método con un tipo receptor, llamado como miembro de la clase sin herencia
  • Despacho estático — selección de función por tipo estático, no por tipo en tiempo de ejecución
  • Cero overhead — se compila como método estático con el receptor como primer parámetro
  • Import obligatorio para usar en otros archivos, se admite alias mediante as
  • Miembros de clase tienen prioridad sobre extension functions con la misma firma
  • Member extensions — extensiones declaradas dentro de una clase tienen acceso a sus miembros
  • Uso práctico — utilidades para String, View, Context, colecciones y construcción de DSL

Desarrollaremos una aplicación móvil llave en mano

IT Sectr crea aplicaciones para iOS y Android para startups y empresas desde 2017. Le asesoraremos y le propondremos la mejor solución.

Discutir el proyecto

Lea también