Sobes.tech
Middle

¿Cuáles son las características del trabajo con constructores e inicialización de objetos en Kotlin?

sobes.tech AI

Respuesta de la IA

En Kotlin, las clases pueden tener un constructor primario y uno o varios constructores secundarios.

Constructor primario:

  • Se declara en la cabecera de la clase:
    class User(val name: String, var age: Int = 0) {
        // cuerpo de la clase
    }
    
  • No tiene cuerpo. El código de inicialización se ejecuta en bloques init.
  • Las propiedades declaradas en el constructor primario con val o var se convierten en propiedades de la clase.
  • Se pueden usar los parámetros del constructor en los bloques init y en la inicialización de propiedades:
    init {
        println("Inicializando usuario $name")
    }
    
    val description = "Usuario: $name, edad: $age"
    
  • Si el constructor primario no tiene anotaciones o modificadores de visibilidad, se puede omitir la palabra clave constructor.

Bloques init:

  • Contienen código de inicialización que se ejecuta al crear una instancia de la clase.
  • Se ejecutan en el orden en que se declaran en la clase.
  • Se ejecutan después de la llamada al constructor primario (si existe), pero antes de los constructores secundarios.

Constructores secundarios:

  • Se declaran con la palabra clave constructor.
  • Pueden delegar la llamada a otro constructor de la misma clase usando this() o al constructor de la clase base usando super(). La llamada a la delegación debe ser la primera instrucción.
    class User(val name: String) {
        constructor(name: String, age: Int) : this(name) {
            println("Constructor secundario")
            // lógica adicional de inicialización
        }
    }
    
  • Si la clase tiene un constructor primario, todos los constructores secundarios deben delegar explícitamente o implícitamente a él usando this().

Orden de inicialización:

  1. Ejecución del código del constructor primario (si existe).
  2. Ejecución de los bloques init en orden.
  3. Ejecución del código del constructor secundario (si se usa).

Ejemplo:

class Example(name: String) {
    init {
        println("Primer bloque init para $name")
    }

    val property1 = "Propiedad 1"

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

    constructor(name: String, age: Int) : this(name) {
        println("Constructor secundario para $name, edad $age")
    }
}

fun main() {
    val ex1 = Example("Usuario1") // Imprime: Primer bloque init para Usuario1, Segundo bloque init para Usuario1
    val ex2 = Example("Usuario2", 30) // Imprime: Primer bloque init para Usuario2, Segundo bloque init para Usuario2, Constructor secundario para Usuario2, edad 30
}

Características clave: sintaxis declarativa del constructor primario, uso de bloques init para lógica de inicialización, delegación explícita en constructores secundarios para garantizar la coherencia en la creación de objetos.