0Pricing
Kotlin Academy · Aula

Funções de extensão: sintaxe e regras de despacho

Escreva funções de extensão e entenda a semântica do despacho estático.

Funções de extensão: sintaxe e regras de despacho é uma aula grátis de Kotlin Academy no CoddyKit. Esta é a aula 1 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de Kotlin Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de Kotlin Academy inclui 4 aulas no total.

O que são funções de extensão

As funções de extensão permitem adicionar novas funções a classes existentes sem modificá-las nem usar herança.

Sintaxe básica de uma função de extensão

Prefixe o nome da função com o tipo que está sendo estendido, chamado de tipo receptor.
fun String.shout(): String = uppercase() + "!"
println("hello".shout())  // HELLO!
fun Int.isEven() = this % 2 == 0
println(4.isEven())  // true

A referência ao próprio objeto nas extensões

Dentro de uma função de extensão, a referência ao próprio objeto aponta para o objeto receptor.
fun List<Int>.secondOrNull(): Int? {
    return if (size >= 2) this[1] else null
}
println(listOf(10, 20, 30).secondOrNull())  // 20
println(listOf(5).secondOrNull())           // null

Despacho estático: extensões não substituem funções

As funções de extensão são resolvidas estaticamente em tempo de compilação com base no tipo declarado — elas são NOT virtuais.
open class Base
class Child : Base()
fun Base.greet() = "Hello from Base"
fun Child.greet() = "Hello from Child"

val obj: Base = Child()
println(obj.greet())  // "Hello from Base" (static dispatch!)

Extensões versus funções-membro

Se uma classe tiver uma função-membro com a mesma assinatura de uma extensão, a função-membro sempre terá prioridade.
class Greeter {
    fun hello() = "member hello"
}
fun Greeter.hello() = "extension hello"  // shadowed!
println(Greeter().hello())  // "member hello"

Extensões para receptores anuláveis

É possível estender tipos anuláveis. Dentro da extensão, trate o valor nulo com verificações apropriadas.
fun String?.orEmpty() = this ?: ""
fun Any?.toStringSafe() = this?.toString() ?: "null"
println(null.orEmpty())  // ""
println(42.toStringSafe())  // "42"

Visibilidade e escopo

As extensões podem ser de nível superior (globais), estar em uma classe (extensões-membro) ou em um arquivo. Elas seguem as regras normais de visibilidade.
// Top-level extension:
fun List<String>.joinUppercase() = joinToString { it.uppercase() }
// Private to file:
private fun String.clean() = trim().lowercase()

Extensões de objetos companheiros

Adicione extensões a um objeto companheiro para estender o espaço de nomes no nível da classe.
class User(val name: String) {
    companion object
}
fun User.Companion.guest() = User("Guest")
val guest = User.guest()

Extensões em tipos da biblioteca padrão

Estenda qualquer tipo — inclusive tipos integrados.
fun Double.roundTo(decimals: Int): Double {
    val factor = Math.pow(10.0, decimals.toDouble())
    return Math.round(this * factor) / factor
}
println(3.14159.roundTo(2))  // 3.14

Organização das extensões

Agrupe as extensões de um tipo em um arquivo dedicado, por exemplo, StringExtensions.kt e DateExtensions.kt.
// StringExtensions.kt
fun String.titleCase() = split(" ")
    .joinToString(" ") {
        it.replaceFirstChar { c -> c.uppercase() }
    }
println("hello world".titleCase())  // Hello World

Extensões não podem acessar membros privados

As extensões só têm acesso a membros públicos e internos — não a membros privados ou protegidos.
class Secret {
    private val key = "hidden"
    val name = "public"
}
fun Secret.reveal() {
    println(name)  // OK
    // println(key)  // Error: key is private
}

Verificação rápida

Se uma função-membro de uma classe e uma função de extensão tiverem a mesma assinatura, qual delas será chamada?

Recapitulação

As funções de extensão adicionam comportamento a qualquer classe sem modificá-la. Elas usam despacho estático (não há substituição). As funções-membro têm prioridade sobre as extensões. Use receptores anuláveis para auxiliares seguros contra valores nulos. Próximo: propriedades de extensão!

Perguntas Frequentes

A aula “Funções de extensão: sintaxe e regras de despacho” é grátis?

Sim — o texto completo de “Funções de extensão: sintaxe e regras de despacho” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de Kotlin Academy, atualize para CoddyKit PRO. O curso de Kotlin Academy inclui 4 aulas no total.

O que vou aprender em “Funções de extensão: sintaxe e regras de despacho”?

Escreva funções de extensão e entenda a semântica do despacho estático. Você pratica Kotlin Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.

Preciso ter experiência prévia para começar Kotlin Academy?

Nenhuma experiência prévia é necessária. Kotlin Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 1 de 4.

Quanto tempo leva a aula “Funções de extensão: sintaxe e regras de despacho”?

A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.

Posso escrever e executar código nesta aula de Kotlin Academy?

Sim. Cada aula de Kotlin Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.

Todas as aulas deste curso

  1. Funções de extensão: sintaxe e regras de despacho
  2. Propriedades de extensão e extensões calculadas
  3. Extensões com escopo e extensões de companion
  4. Extensões práticas: auxiliares de Context, View e String
← Voltar para Kotlin Academy