28 - POO - propiedades y sus métodos opcionales set y get

Hemos visto que cuando definimos una propiedad pública podemos acceder a su contenido para modificarla o consultarla desde donde definimos un objeto.

A una propiedad podemos asociarle un método llamado set en el momento que se le asigne un valor y otro método llamado get cuando se accede al contenido de la propiedad.

Estos métodos son opcionales y nos permiten validar el dato a asignar a la propiedad o el valor de retorno.

Cuando no se implementan estos métodos el mismo compilador crea estos dos métodos por defecto.

Problema 1

Declarar una clase llamada persona con dos propiedades que almacenen el nombre y la edad de la persona. En la propiedad nombre almacenar siempre en mayúscula el nombre y cuando se recupere su valor retornarlo entre paréntesis, también controlar que no se pueda ingresar una edad con valor negativo, en dicho caso almacenar un cero.

Proyecto125 - Principal.kt

class Persona {
    var nombre: String = ""
    set(valor) {
        field = valor.toUpperCase()
    }
    get() {
        return "(" + field + ")"
    }

    var edad: Int = 0
    set(valor) {
        if (valor >= 0)
            field = valor
        else
            field = 0
    }
}

fun main(parametro: Array<String>) {
    val persona1 = Persona()
    persona1.nombre = "juan"
    persona1.edad = 23
    println(persona1.nombre)   // Se imprime:  (JUAN)
    println(persona1.edad)      // Se imprime:  23
    persona1.edad = -50
    println(persona1.edad)      // Se imprime:  0
}

Primero definimos la propiedad nombre de tipo String:

    var nombre: String = ""

En la línea inmediatamente siguiente definimos el método set (que no lleva la palabra clave fun) y que tiene un parámetro que no se indica el tipo porque es del mismo tipo que la propiedad nombre. Dentro del método set podemos modificar el contenido de la propiedad nombre mediante la palabra clave field (en este problema guardamos el dato que llega pero convertido a mayúsculas):

    set(valor) {
        field = valor.toUpperCase()
    }

En el caso que la propiedad implemente el método get también lo hacemos antes o después del método set si lo tiene:

    get() {
        return "(" + field + ")"
    }

La propiedad edad solo implementa el método set donde verificamos si el parámetro que recibe es negativo almacenamos en la propiedad el valor 0 sino almacenamos el valor tal cual llega.

También es muy importante entender que cuando definimos un objeto de la clase persona y le asignamos un valor a una propiedad en realidad se está ejecutando un método:

    val persona1 = Persona()
    persona1.nombre = "juan"  //se ejecuta el método set de la propiedad nombre

Luego de esta asignación en la propiedad nombre se almacenó el String "JUAN" en mayúsculas ya que eso hace el método set.

En la asignación:

    persona1.edad = 23

se almacena el número 23 ya que es mayor o igual a cero.

Podemos comprobar los valores de las propiedades:

    println(persona1.nombre)   // Se imprime:  (JUAN)
    println(persona1.edad)      // Se imprime:  23

Si tratamos de fijar un valor menor a cero en la propiedad edad:

    persona1.edad = -50

Luego no se carga ya que en el método set verificamos el dato que llega y cargamos en caso que sea negativo el valor cero:

    println(persona1.edad)      // Se imprime:  0

Problemas propuestos

  • Confeccionar una clase que represente un Empleado. Definir como propiedades su nombre y su sueldo.
    No permitir que se cargue un valor negativo en su sueldo.
    Codificar el método imprimir en la clase.
  • Plantear una clase llamada Dado. Definir una propiedad llamada valor que permita cargar un valor comprendido entre 1 y 6 si llega un valor que no está comprendido en este rango se debe cargar un 1.
    Definir dos métodos, uno que genere un número aleatorio entre 1 y 6 y otro que lo imprima.
    Al constructor llega el valor inicial que debe tener el dado (tratar de enviarle el número 7)
Solución
Proyecto126

class Empleado(var nombre: String, sueldo: Double) {

    var sueldo: Double = 0.0
    set(valor) {
        if (valor < 0)
            field = 0.0
        else
            field = valor
    }

    init {
        this.sueldo = sueldo
    }

    fun imprimir() {
        println("$nombre tiene un sueldo de $sueldo")
    }
}

fun main(parametro: Array<String>) {
    val empleado1 = Empleado("Juan", 12000.50)
    empleado1.imprimir()
    val empleado2 = Empleado("Ana", -1200.0)
    empleado2.imprimir()
}




Proyecto127

class Dado(valor: Int){
    var valor: Int = 1
    set(valor) {
        if (valor >=1 && valor <= 6)
            field = valor
        else
            field = 1
    }

    init {
        this.valor = valor
    }

    fun tirar() {
        valor = ((Math.random() * 6) + 1).toInt()
    }

    fun imprimir() = println("Valor del dado: $valor")
}

fun main(parametro: Array<String>) {
    val dado1 = Dado(7)
    dado1.imprimir()
    dado1.tirar()
    dado1.imprimir()
}