Constructores
Explicación de los tipos de constructores.
DEFINICIÓN
val azulito: Slime = Slime()
Si se fija, en el ejemplo superior estamos llamando a una función para inicializar nuestra variable.
Esta función especial que inicializa una instancia de una clase se llama constructor.
Sí no se provee un constructor a la clase (como era el caso en nuestra clase Slime, el compilador genera uno sin parámetro por defecto. Como el del ejemplo.
Los constructores pueden ser primarios o secundarios.
CONSTRUCTOR PRIMARIO
El constructor primario es parte de la cabecera de una clase. Este recibe como argumentos, aquellos datos que necesitas explícitamente para inicializar las propiedades al crear el objeto.
class Slime constructor(val name: String = "slimePorDefecto"){
var hp: Int = 100
var ap: Int = 5
var alive: Boolean = true
/*...*/
}
El constructor utiliza la palabra reservada constructor
. Sin embargo, si no tiene anotaciones ni modificadores, se puede omitir.
class Slime (val name: String = "slimePorDefecto"){
/*...*/
Como puede ver, el constructor puede tener un valor por defecto o puede no tenerlo, igual que los parámetros de una función, sin embargo, ahora puedo cambiar el nombre de mi objeto "azulito" aunque sea un val.
val azulito: Slime = Slime("Azulito")
Bloques de inicialización
Los bloques de inicialización permiten añadir lógica a la inicialización de las propiedades.
Su sintaxis es la siguiente:
class Slime constructor(val name: String = "slimePorDefecto",
hp: Int = 100,
ap: Int = 5) {
var hp: Int
var ap: Int
var alive: Boolean = true
init {
if (hp <= 100) this.hp = hp else this.hp = 100
if (ap <= 5) this.ap = ap else this.ap = 5
}
Visibilidad del constructor
El constructor, igual que la clase en sí se puede modificar con los modificadores de visibilidad de Kotlin:
private
: Marca una declaración como visible en la clase o archivo actual.protected
: Marca una declaración como visible en la clase y subclases de la misma.internal
: Marca una declaración como visible en el módulo actual.public
: Marca una declaración como visible en todas partes.
Esto lo utilizaremos mucho más para aplicar la Herencia y el principio de Ocultación más adelante.
CONSTRUCTOR SECUNDARIO
Si la lista de argumentos del constructor primario no satisface, en algun caso, la creación de objetos, se pueden crear constructores secundarios dentro del cuerpo de la clase.
Un ejemplo que podría darse en nuestro caso:
Constructor primario solo para el nombre.
Constructor secundario si me dan nombre y otros dos argumentos (hp y ap).
val BAD_WORDS: Array<String> = arrayOf("Feo", "Tonto", "CuatroOjos")
class Slime (name: String = "slimePorDefecto"){
val name: String
var hp: Int
var ap: Int
var alive: Boolean = true
init {
if (name in BAD_WORDS) this.name = "BuenIntento" else this.name = name
this.hp = 100
this.ap = 5
}
constructor(name: String, hp: Int, ap: Int): this(name) {
if (hp <= 100) this.hp = hp else this.hp = Random.nextInt(0, 100)
if (ap <= 5) this.ap = ap else this.ap = Random.nextInt(0, 5)
}
/*...*/
Se pueden tener tantos constructores secundarios como sean necesarios. Sin embargo, el ejemplo anterior se podría haber realizado igual de bien con un constructor primario y un bloque init:
val BAD_WORDS: Array<String> = arrayOf("Feo", "Tonto", "CuatroOjos")
class Slime (name: String = "slimePorDefecto", hp: Int = 100, ap: Int = 5){
val name: String
var hp: Int
var ap: Int
var alive: Boolean = true
init {
if (name in BAD_WORDS) this.name = "BuenIntento" else this.name = name
if (hp <= 100) this.hp = hp else this.hp = Random.nextInt(0, 100)
if (ap <= 5) this.ap = ap else this.ap = Random.nextInt(0, 5)
/*...*/
}
Y con eso hecho, si inicializamos un objeto de ésta clase intentando abusar recibiré lo siguiente:
val azulito: Slime = Slime("CuatroOjos", 1000000, 500)
println("name: " + azulito.name)
println("hp: " + azulito.hp)
println("ap: " + azulito.ap)
println("alive: " + azulito.alive)
/* Respuesta
name: BuenIntento
hp: 45
ap: 3
alive: true
*/
Last updated