Sobes.tech
Junior

Explique o que é um 'companion object' na linguagem Kotlin e em que casos deve ser utilizado.

sobes.tech IA

Resposta da IA

companion object — é um objeto especial associado a uma classe, mas que não é uma instância dela. Funciona como membros estáticos em Java.

Pontos-chave:

  • Declarado dentro da classe usando a palavra-chave companion object.
  • Tem acesso aos membros privados da classe.
  • Pode ter um nome, mas geralmente é omitido (usa-se o nome Companion).
  • Os membros do companion object podem ser acessados diretamente pelo nome da classe, sem criar uma instância.

Exemplos de uso:

  • Métodos de fábrica: Para criar instâncias da classe com lógica de inicialização mais complexa do que os construtores normais.

    class MyClass private constructor(val value: String) { // Construtor privado
    
        companion object {
            fun create(input: String): MyClass { // Método de fábrica
                // Lógica de processamento do input
                return MyClass("Processed: $input")
            }
        }
    }
    
    fun main() {
        val instance = MyClass.create("some data") // Uso do método de fábrica
        println(instance.value)
    }
    
  • Constantes ao nível da classe: Para definir valores que devem estar disponíveis sem criar uma instância.

    class Constants {
        companion object {
            const val DEFAULT_VALUE = "default" // Constante
        }
    }
    
    fun main() {
        println(Constants.DEFAULT_VALUE) // Acesso à constante
    }
    
  • Implementação de interfaces: companion object pode implementar interfaces, o que é útil para simular fábricas estáticas com funcionalidade comum.

    interface Factory<T> {
        fun create(): T
    }
    
    class MyData(val id: Int) {
        companion object : Factory<MyData> {
            private var nextId = 0
            override fun create(): MyData {
                return MyData(nextId++)
            }
        }
    }
    
    fun main() {
        val data1 = MyData.create()
        val data2 = MyData.create()
        println(data1.id)
        println(data2.id)
    }
    
  • Extensões: companion object pode ser estendido, permitindo adicionar métodos "estáticos" à classe de fora.

    class MyUtil {
        companion object {
            // Objeto companion vazio
        }
    }
    
    fun MyUtil.Companion.helperMethod() { // Extensão do objeto companion
        println("Called helper method")
    }
    
    fun main() {
        MyUtil.helperMethod()
    }
    

De modo geral, companion object deve ser usado quando é necessária funcionalidade relacionada à classe, mas que não requer uma instância dela. É uma forma mais idiomática em Kotlin de alcançar o que em Java é feito com membros estáticos, oferecendo maior flexibilidade (por exemplo, na implementação de interfaces e extensões). Não deve ser abusado para armazenar estado que deve ser único para cada instância.