---
title: "Operator Overloading em Kotlin: Como Funciona | Kotlin Brasil"
url: "https://kotlin.dev.br/glossario/operator-overloading/"
markdown_url: "https://kotlin.dev.br/glossario/operator-overloading.MD"
description: "Aprenda o que é Operator Overloading em Kotlin, como sobrecarregar operadores e criar APIs mais expressivas."
date: "2026-02-15"
author: "Karina Melo"
---

# Operator Overloading em Kotlin: Como Funciona | Kotlin Brasil

Aprenda o que é Operator Overloading em Kotlin, como sobrecarregar operadores e criar APIs mais expressivas.


## O que é Operator Overloading em Kotlin?

Operator Overloading (sobrecarga de operadores) permite **redefinir o comportamento de operadores** como `+`, `-`, `*`, `[]`, `==` e outros para suas próprias classes. Você escreve funções especiais marcadas com `operator` e pronto — seus objetos passam a funcionar com a sintaxe natural de operadores.

### Exemplo básico: somando vetores

```kotlin
data class Vetor(val x: Double, val y: Double) {
    operator fun plus(outro: Vetor) = Vetor(x + outro.x, y + outro.y)
    operator fun minus(outro: Vetor) = Vetor(x - outro.x, y - outro.y)
    operator fun times(escalar: Double) = Vetor(x * escalar, y * escalar)
}

fun main() {
    val a = Vetor(1.0, 2.0)
    val b = Vetor(3.0, 4.0)

    println(a + b)      // Vetor(x=4.0, y=6.0)
    println(a - b)      // Vetor(x=-2.0, y=-2.0)
    println(a * 3.0)    // Vetor(x=3.0, y=6.0)
}
```

### Principais operadores

| Operador | Função | Exemplo |
|---|---|---|
| `+` | `plus` | `a + b` |
| `-` | `minus` | `a - b` |
| `*` | `times` | `a * b` |
| `/` | `div` | `a / b` |
| `[]` | `get` / `set` | `a[i]` |
| `==` | `equals` | `a == b` |
| `>` `<` | `compareTo` | `a > b` |
| `in` | `contains` | `x in a` |

### Operadores de acesso: `get` e `set`

```kotlin
class Matriz(private val dados: Array<IntArray>) {
    operator fun get(linha: Int, coluna: Int): Int = dados[linha][coluna]
    operator fun set(linha: Int, coluna: Int, valor: Int) {
        dados[linha][coluna] = valor
    }
}

fun main() {
    val m = Matriz(arrayOf(intArrayOf(1, 2), intArrayOf(3, 4)))
    println(m[0, 1]) // 2
    m[1, 0] = 99
    println(m[1, 0]) // 99
}
```

### Operador `invoke`

O operador `invoke` permite chamar um objeto como se fosse uma função:

```kotlin
class Validador(val regex: Regex) {
    operator fun invoke(valor: String): Boolean = regex.matches(valor)
}

fun main() {
    val validarEmail = Validador(Regex("^[\\w.-]+@[\\w.-]+\\.[a-z]{2,}$"))
    println(validarEmail("karina@kotlin.dev.br")) // true
    println(validarEmail("invalido"))              // false
}
```

### Operadores de atribuição composta

Além dos operadores básicos, você pode sobrecarregar os operadores de atribuição composta como `+=`, `-=` e `*=`. O Kotlin resolve automaticamente `a += b` como `a = a.plus(b)` se a variável for `var`, ou você pode definir `plusAssign` explicitamente para tipos mutáveis:

```kotlin
class Carrinho {
    private val itens = mutableListOf<String>()

    operator fun plusAssign(item: String) {
        itens.add(item)
    }

    operator fun minusAssign(item: String) {
        itens.remove(item)
    }

    operator fun contains(item: String): Boolean = item in itens

    override fun toString() = "Carrinho(itens=$itens)"
}

fun main() {
    val carrinho = Carrinho()
    carrinho += "Teclado"
    carrinho += "Mouse"
    carrinho += "Monitor"
    carrinho -= "Mouse"

    println(carrinho)                // Carrinho(itens=[Teclado, Monitor])
    println("Teclado" in carrinho)   // true
    println("Mouse" in carrinho)     // false
}
```

### Operadores como extensões

Você não precisa ser o dono da classe para definir operadores. Funções de extensão com `operator` funcionam perfeitamente:

```kotlin
data class Dinheiro(val centavos: Long) {
    override fun toString(): String {
        val reais = centavos / 100
        val cents = centavos % 100
        return "R$ $reais,${cents.toString().padStart(2, '0')}"
    }
}

operator fun Dinheiro.plus(outro: Dinheiro) = Dinheiro(centavos + outro.centavos)
operator fun Dinheiro.times(quantidade: Int) = Dinheiro(centavos * quantidade)
operator fun Dinheiro.compareTo(outro: Dinheiro) = centavos.compareTo(outro.centavos)

fun main() {
    val preco = Dinheiro(2990)       // R$ 29,90
    val frete = Dinheiro(1500)       // R$ 15,00
    val total = preco + frete
    val triplo = preco * 3

    println(total)   // R$ 44,90
    println(triplo)  // R$ 89,70
    println(preco > frete) // true
}
```

### Casos de Uso no Mundo Real

- **Cálculos financeiros**: criar tipos como `Dinheiro` ou `Moeda` com operadores aritméticos, evitando erros de arredondamento com `Double` e garantindo segurança de tipo.
- **Bibliotecas matemáticas e científicas**: definir operações sobre vetores, matrizes, números complexos e outras estruturas algébricas, permitindo que fórmulas no código pareçam com fórmulas matemáticas.
- **DSLs (Domain-Specific Languages)**: usar `invoke`, `get` e `contains` para criar APIs fluentes e naturais, como builders de consultas SQL ou configurações.
- **Coleções customizadas**: sobrecarregar `get`, `set`, `contains`, `plusAssign` e `iterator` para criar estruturas de dados com interface familiar.

### Boas Práticas

- O operador deve ter um **significado intuitivo** para quem lê o código. Somar dois vetores faz sentido; "somar" dois usuários, nem tanto.
- Mantenha a semântica esperada: `plus` deve ser comutativo quando possível, `compareTo` deve ser transitivo, `equals` deve ser reflexivo, simétrico e transitivo.
- Prefira operadores como extensões quando a classe não é sua. Isso mantém o código desacoplado e permite adicionar operadores a classes de bibliotecas de terceiros.
- Documente operadores não óbvios. Se o significado de `*` na sua classe não for imediatamente claro, adicione um comentário explicando.
- Evite sobrecarregar operadores em excesso. Se a classe tem dez operadores, talvez ela esteja fazendo coisas demais.

### Erros Comuns

- **Usar operator overloading sem semântica clara**: definir `+` para concatenar objetos que não fazem sentido juntos confunde outros desenvolvedores e torna o código difícil de manter.
- **Esquecer a palavra-chave `operator`**: sem ela, a função é apenas uma função normal chamada `plus` ou `times`, e o operador `+` ou `*` não vai funcionar.
- **Confundir `plus` com `plusAssign`**: se a classe é imutável, defina apenas `plus` e use `var`. Se é mutável, defina `plusAssign`. Definir ambos na mesma classe gera ambiguidade com `var`.
- **Não respeitar contratos de `equals` e `hashCode`**: ao sobrecarregar `equals`, sempre sobrescreva `hashCode` também. Caso contrário, a classe vai se comportar de forma inesperada em coleções como `HashSet` e `HashMap`.
- **Ignorar efeitos colaterais em operadores**: operadores devem ser puros quando possível. Um `plus` que faz chamada de rede ou modifica estado global é um design perigoso.

### Perguntas Frequentes

**Posso criar operadores novos que não existem em Kotlin?** Não. Kotlin tem um conjunto fixo de operadores que podem ser sobrecarregados. Você não pode inventar símbolos novos como `<>` ou `**`. A lista completa está na documentação oficial.

**Operator overloading afeta a performance?** Na maioria dos casos, não há impacto significativo. O compilador transforma operadores em chamadas de função normais. Com `data class` e `inline class`, o overhead é mínimo ou zero.

**Qual a diferença entre `==` e `===` ao sobrecarregar?** O operador `==` chama a função `equals` e pode ser sobrecarregado. Já o `===` verifica identidade referencial (se dois objetos são a mesma instância na memória) e não pode ser sobrecarregado.

**Posso sobrecarregar operadores em interfaces?** Sim. Você pode declarar funções `operator` em interfaces, e as classes que implementarem a interface terão o operador disponível.

### Termos Relacionados

- [Extension Function](/glossario/extension-function) — funções de extensão que podem definir operadores para classes existentes
- [Data Class](/glossario/data-class) — classes que já implementam `equals`, `hashCode` e outros operadores automaticamente
- [Infix Function](/glossario/infix) — outra forma de criar sintaxe expressiva em Kotlin
- [Inline Class](/glossario/inline-class) — classes wrapper com zero overhead que combinam bem com operadores

Quando bem aplicado, operator overloading deixa o código expressivo e natural.
