Sobes.tech
Middle

Quais são as características do trabalho com construtores e inicialização de objetos em Kotlin?

sobes.tech IA

Resposta da IA

No Kotlin, as classes podem ter um construtor primário e um ou mais construtores secundários.

Construtor primário:

  • Declarado na cabeça da classe:
    class User(val name: String, var age: Int = 0) {
        // corpo da classe
    }
    
  • Não possui corpo. O código de inicialização é executado nos blocos init.
  • As propriedades declaradas no construtor primário com val ou var tornam-se propriedades da classe.
  • Pode-se usar os parâmetros do construtor nos blocos init e na inicialização de propriedades:
    init {
        println("Inicializando usuário $name")
    }
    
    val description = "Usuário: $name, idade: $age"
    
  • Se o construtor primário não tiver anotações ou modificadores de visibilidade, a palavra-chave constructor pode ser omitida.

Blocos init:

  • Contêm código de inicialização que é executado ao criar uma instância da classe.
  • São executados na ordem em que são declarados.
  • São executados após a chamada ao construtor primário (se houver), mas antes dos construtores secundários.

Construtores secundários:

  • Declarados com a palavra-chave constructor.
  • Podem delegar a chamada para outro construtor da mesma classe usando this() ou para o construtor da classe base usando super(). A chamada de delegação deve ser a primeira instrução.
    class User(val name: String) {
        constructor(name: String, age: Int) : this(name) {
            println("Construtor secundário")
            // lógica adicional de inicialização
        }
    }
    
  • Se a classe tiver um construtor primário, todos os construtores secundários devem delegar explicitamente ou implicitamente a ele usando this().

Ordem de inicialização:

  1. Execução do código do construtor primário (se houver).
  2. Execução dos blocos init na ordem.
  3. Execução do código do construtor secundário (se usado).

Exemplo:

class Example(name: String) {
    init {
        println("Primeiro bloco init para $name")
    }

    val property1 = "Propriedade 1"

    init {
        println("Segundo bloco init para $name")
    }

    constructor(name: String, age: Int) : this(name) {
        println("Construtor secundário para $name, idade $age")
    }
}

fun main() {
    val ex1 = Example("Usuário1") // Imprime: Primeiro bloco init para Usuário1, Segundo bloco init para Usuário1
    val ex2 = Example("Usuário2", 30) // Imprime: Primeiro bloco init para Usuário2, Segundo bloco init para Usuário2, Construtor secundário para Usuário2, idade 30
}

Características principais: sintaxe declarativa do construtor primário, uso de blocos init para lógica de inicialização, delegação explícita em construtores secundários para garantir a coerência na criação de objetos.