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.