Constructores En Kotlin

En este tutorial aprenderás acerca del uso de constructores en Kotlin, para crear las instancias de tu clase en memoria e inicializar sus propiedades. También verás que existen constructores primarios y secundarios.

¿Qué Es Un Constructor?

Un constructor es una función especial que se usa para inicializar el contenido de las nuevas instancias de una clase.

A diferencia de otros lenguajes, no usas la palabra new para crear el objeto, si no que llamas al constructor como una función normal.

class Player

val player1 = Player()

Como ves, usas el nombre de la clase para realizar la llamada.

Si no provees un constructor, entonces el compilador de Kotlin genera uno sin parámetros por defecto.

Los constructores de una clase pueden escribirse como primarios y secundarios. Observa de qué se trata.

Constructor Primario

El constructor primario o principal, hace parte de la cabecera de la clase. Este recibe como argumentos, aquellos datos que necesitas explicitamente para inicializar las propiedades al crear el objeto.

En su sintaxis concisa, si declara con val o var antes del parámetro de un constructor primario, creas una propiedad automáticamente en la clase.

Usa la palabra reservada constructor luego del nombre de la clase:

class ClaseEjemplo constructor(val propiedad1:Tipo, var propiedad2:Tipo, ...)

Si no tienes anotaciones o modificadores de visibilidad puedes omitirla:

class ClaseEjemplo(val propiedad1:Tipo, var propiedad2:Tipo, ...)

Ejemplo De Constructor Primario

Supón que estamos creando un juego RPG y necesitamos modelar la clase para las armas que usarán los personajes de los jugadores. Se necesitarán los atributos para el daño de ataque y la velocidad de golpe.

La definición de la clase junto con constructor primario se vería así:

class Weapon(val attack: Int, val speed: Double)

Al crear la instancia de una nueva arma, llamamos al constructor como una función y pasamos los argumentos para las propiedades requeridas:

fun main() {
    val weapon1 = Weapon(3, 0.5)
    println("Arma 1 (ataque:${weapon1.attack}, velocidad: ${weapon1.speed})")
}

Al imprimir el contenido del objeto creado se reflejarían las propiedades establecidas para weapon1.

Arma 1 (ataque:3, velocidad: 0.5)

Bloques De Inicialización

Es posible expandir la inicialización de las propiedades usando la sección init en la clase para el constructor primario.

En ella incluyes como cuerpo la lógica de asignación.

Por ejemplo, la clase Weapon puede ser escrita en forma expandida de la siguiente forma:

class Weapon(attack: Int, speed: Double) {
    val attack: Int
    val speed: Double

    init {
        this.attack = attack
        this.speed = speed
    }
}

Con la sintaxis completa, las propiedades son declaradas al interior de la clase y los parámetros pasan a solo ser parámetros de constructor sin val ni var.

Si los nombres de los parámetros del constructor se llaman igual a las propiedades, usa la expresión this para acceder a la propiedad de la instancia que intentas generar con el constructor.

Visibilidad Del Constructor

Cambia la visibilidad de tus constructores en Kotlin usando los modificadores existentes (public, internal, protected y private).

La sintaxis consiste en usar la palabra reservada constructor y anteponer el modificador.

class Item internal constructor(name: String)

Constructores Secundarios

Si la lista de argumentos del constructor primario no satisface la creación de tu objeto en alguna circunstancia, entonces puedes crear un constructor secundario a la medida.

Su declaración se realiza a través de constructor al interior de la clase.

Si tienes un constructor primario es obligatorio usar la expresión this para delegarle los parámetros que requiera.

Luego escribe la lógica de inicialización en el bloque.

class Clase{
    constructor(parametro1:Tipo, parametro2:Tipo /*,..*/): this(/*parametros*/){
        /* Cuerpo de constructor */
    }
}

Ejemplo De Constructor Primario Y Secundario

Se requiere crear una clase de contactos que contenga los atributos Id y Nombre. Se pueden crear contactos con tan solo el nombre y el Id autogenerado. O también con ambos valores.

Esto puedes solucionarlo así:

class Contact(var name: String) {
    var id: String

    init {
        id = UUID.randomUUID().toString()
    }

    constructor(id:String, name: String) : this(name){
        this.id = id
    }
}

Declaras un constructor primario con el nombre y la autogeneración del Id en el bloque de inicialización.

Luego en el constructor secundario recibes ambos parámetros. Delegas hacia el constructor primario el nombre y el id lo reemplazas.

De esta forma puedes crear los dos tipos de contactos:

Contact("Erika")
Contact("C-1", "Mauricio")

Ejemplo Con Dos Constructores Secundarios

Sin embargo, la delegación del ejemplo anterior no es necesaria, ya que no usas un valor autogenerado en el Id en la llamada del constructor con dos parámetros.

En cambio sí reescribes con dos constructores secundarios la clase, evitarías esa ejecución extra:

class Contact {
    var id: String
    var name: String

    constructor(name: String) {
        this.name = name
        id = UUID.randomUUID().toString()
    }

    constructor(id: String, name: String){
        this.id = id
        this.name = name
    }
}

Y al instanciar sería exactamente igual:

val contacto1 = Contact("Erika")
val contacto2 = Contact("C-1", "Mauricio")

¿Qué Sigue?

En este tutorial aprendiste sobre constructores en Kotlin. Viste la sintaxis de los constructores primarios y secundarios. El siguiente paso es ir al tutorial de propiedades miembros en clases.

Únete Al Discord De Develou

Si tienes problemas con el código de este tutorial, preguntas, recomendaciones o solo deseas discutir sobre desarrollo Android conmigo y otros desarrolladores, únete a la comunidad de Discord de Develou y siéntete libre de participar como gustes. ¡Te espero!