DEV Community

Cover image for Sobrecarga de operadores do Kotlin
Alex Felipe
Alex Felipe

Posted on

3

Sobrecarga de operadores do Kotlin

Um detalhe bastante curioso no Kotlin é que podemos "somar", "subtrair" ou fazer diversas operações com os nossos objetos. Um exemplo bastante interessante seria a soma de listas:

val words = listOf("alex", "felipe")
val numbers = listOf(1, 2, 3)
val someList = words + numbers
println(someList)
println(words)
println(numbers)
Enter fullscreen mode Exit fullscreen mode

Qual o resultado você espera? Vejamos:

[alex, felipe, 1, 2, 3]
[alex, felipe]
[1, 2, 3]
Enter fullscreen mode Exit fullscreen mode

Olha que interessante! Uma nova lista foi criada adicionando os itens de cada lista, e mais, a soma não é restrita apenas entre as listas, podemos somar com qualquer objeto, até mesmo os nossos:

data class User(
    val id: Long,
    val name: String
)

val numbersWithUser = listOf(1, 2) + User(
    id = 1,
    name = "alexfelipe"
)
val wordsWithNumber = listOf(
    "alex",
    "felipe"
) + 1
println(numbersWithUser)
println(wordsWithNumber)
Enter fullscreen mode Exit fullscreen mode

E o resultado que temos é:

[1, 2, User(id=1, name=alexfelipe)]
[alex, felipe, 1]
Enter fullscreen mode Exit fullscreen mode

Neste momento você pode pensar:

"Como isso é possível?" 🤔

Conhecendo a sobrecarga de operadores

Essa funcionalidade é conhecida como sobrecarga de operadores ou operator overloading, embora o nome poça assustar, basicamente, são métodos "especiais" com a keyword operator que permitem adicionar o comportamento que desejamos.

Vamos considerar o exemplo do +, ele é traduzido para o método plus(). Podemos até mesmo ver algumas implementações na interface de Collection:

public operator fun <T> Collection<T>.plus(element: T): List<T> {
    val result = ArrayList<T>(size + 1)
    result.addAll(this)
    result.add(element)
    return result
}

public operator fun <T> Iterable<T>.plus(elements: Iterable<T>): List<T> {
    if (this is Collection) return this.plus(elements)
    val result = ArrayList<T>()
    result.addAll(this)
    result.addAll(elements)
    return result
}
Enter fullscreen mode Exit fullscreen mode

Veja que tem mais de uma implementação e é por isso que podemos somar listas com listas ou listas com objetos e por ai vai... Aqui você pode ver alguns operadores comuns:

Expressão Traduzido para
a + b a.plus(b)
a - b a.minus(b)
a * b a.times(b)
a / b a.rem(b)
a..b a.rangeTo(b)

Em outras palavras, se você é capaz de fazer alguma dessas operações com objetos em Kotlin, é porque existe essa sobrecarga!

Implementando sobrecarga de operadores

Inclusive, podemos implementar operadores em nossas classes:

data class Product(
    val id: Long,
    val name: String,
    val description: String
)

class Cart(
   val products: List<Product> = listOf()
) {
    operator fun plus(product: Product): Cart =
        Cart(products + product)
}
Enter fullscreen mode Exit fullscreen mode

Nesta implementação, podemos criar novos carrinhos com os produtos que desejamos somar:

val cart = Cart()
val cartWithKeyboard = cart + Product(
    id = 1,
    name = "Teclado mecânico",
    description = "Teclado com switches brown"
)
println(cartWithKeyboard.products)
val cartWithTShirt = cartWithKeyboard + Product(
    id = 2,
    name = "Camiseta",
    description = "Material 100% algodão"
)
println(cartWithTShirt.products)
Enter fullscreen mode Exit fullscreen mode

Olha só o resultado que temos:

[Product(id=1, name=Teclado mecânico, description=Teclado com switches brown)]
[Product(id=1, name=Teclado mecânico, description=Teclado com switches brown), Product(id=2, name=Camiseta, description=Material 100% algodão)]
Enter fullscreen mode Exit fullscreen mode

Interessante, né? Outras possibilidades de implementação seriam:

  • somar objetos de pedidos e o retorno ser um resumo com todos os produtos, quantidades e valores somados.
  • somar objetos de pagamentos ou taxas para obter o valor final com as adições
  • somar um usuário e um produto para criar um pedido

Enfim, uma série de ações comuns no nosso dia a dia.

Outros casos de uso de operadores

Atualmente existem diversas implementações de operadores, se observarmos a própria Collection, identificamos que é possível subtrair também:

val words = listOf("alex", "felipe", "instrutor", "alura") - "felipe"
val numbers = listOf(1, 2, 3) - 2
println(words)
println(numbers)
Enter fullscreen mode Exit fullscreen mode

Veja o resultado:

[alex, instrutor, alura]
[1, 3]
Enter fullscreen mode Exit fullscreen mode

Ou seja, uma forma mais sucinta de criar uma lista nova sem os elementos que não queremos!

E não para por aqui, se pegarmos classes como BigDecimal, podemos até mesmo fazer operações aritméticas sem problemas:

val total = BigDecimal("2.99") + BigDecimal("4.35")
println(total)
Enter fullscreen mode Exit fullscreen mode

E chegamos no seguinte resultado:

7.34
Enter fullscreen mode Exit fullscreen mode

O mesmo resultado sem a sobrecarga de operador seria assim:

val total = BigDecimal("2.99")
    .add(BigDecimal("4.35"))
Enter fullscreen mode Exit fullscreen mode

Para saber mais: outros tipos de operadores

Neste artigo foquei na sobrecarga de operadores aritméticos, mas existem outras possibilidades, operações unárias e binárias, sendo que as aritméticas fazem parte das binárias.

O que achou da sobrecarga de operadores no Kotlin? Já usava no seu código? Compartilhe sua experiência nos comentários

Heroku

Simplify your DevOps and maximize your time.

Since 2007, Heroku has been the go-to platform for developers as it monitors uptime, performance, and infrastructure concerns, allowing you to focus on writing code.

Learn More

Top comments (0)

Postmark Image

Speedy emails, satisfied customers

Are delayed transactional emails costing you user satisfaction? Postmark delivers your emails almost instantly, keeping your customers happy and connected.

Sign up

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay