33 - Objetos: acceso a atributos de una clase

Los atributos que se definen en una clase solo pueden ser accedidos dentro de los métodos de la misma clase.

Si necesitamos consultar el valor de un atributo o modificar su valor se hace a través de un método.

Problema 1:

Confeccionar una clase que represente un empleado. Definir como atributos su nombre y su sueldo.
En el bloque principal del programa definir dos objetos de la clase Empleado e imprimir el nombre del empleado con sueldo mayor, además fijar su sueldo con el valor 1000.

Programa: ejercicio138.rb

class Empleado

  def initialize (nombre, sueldo)
    @nombre = nombre
    @sueldo = sueldo
  end

  def imprimir
    puts "Nombre: #{@nombre}"
    puts "Sueldo: #{@sueldo}"
  end

  def sueldo
    @sueldo
  end

  def sueldo=(sueldo)
    @sueldo = sueldo
  end

end


empleado1 = Empleado.new "juan", 500
empleado2 = Empleado.new "ana", 700
empleado1.imprimir
empleado2.imprimir
if empleado1.sueldo < empleado2.sueldo
  empleado1.sueldo = 1000
elsif empleado2.sueldo < empleado1.sueldo
  empleado2.sueldo = 1000
end  
puts "Luego de modificar sueldo"
empleado1.imprimir
empleado2.imprimir

Lo primero que hay que decir que el objeto empleado1 no puede acceder al atributo @sueldo:

if empleado1.@sueldo < empleado2.@sueldo

Esto debido que los objetos no pueden acceder a los atributos.

Para acceder al contenido de un atributo debemos definir un método que retorne su valor:

  def sueldo
    @sueldo
  end

Es común definir el nombre del método con el mismo nombre del atributo sin el caracter @:

  def sueldo
    @sueldo
  end

Ahora teniendo el método "sueldo" podemos acceder al atributo @sueldo:

if empleado1.sueldo < empleado2.sueldo
  empleado1.sueldo = 1000
elsif empleado2.sueldo < empleado1.sueldo
  empleado2.sueldo = 1000
end  

Por otro lado tampoco podemos modificar un atributo directamente:

empleado1.@sueldo = 1000

Para poder solucionar esto definimos un método que llegue el valor a almacenar en el atributo:

  def sueldo=(sueldo)
    @sueldo = sueldo
  end

Es común definir el nombre del método con el mismo nombre del atributo más el caracter =

Luego podemos cambiar el valor del atributo llamando a este método con la siguiente sintaxis:

  empleado1.sueldo = 1000

Tener en cuenta que se esta llamando al método sueldo= y pasando el valor 1000.

Problema 2:

Confeccionar una clase que represente un dado. Definir como atributo el valor del dado.
Permitir acceder al atributo solo para consultar su valor y no modificarlo.
Plantear un método llamado "tirar" que genere un valor aleatorio entre 1 y 6.

Definir dos objetos de la clase Dado y mostrar la suma de los dos dados.

Programa: ejercicio139.rb

class Dado

  def initialize
    @nro = 1
  end

  def tirar
    @nro = rand(6) + 1
  end

  def imprimir
    puts "Valor del dado #{@nro}"
  end

  def nro
    @nro
  end

end


dado1 = Dado.new
dado2 = Dado.new
dado1.tirar
dado1.imprimir
dado2.tirar
dado2.imprimir
suma = dado1.nro + dado2.nro
puts "La suma de los dos dados es #{suma}"

En este problema vemos las ventajas de que los atributos sean solo accedidos dentro de la clase y no desde fuera. Hemos definido solo un método para poder acceder al valor almacenado en el atributo @nro:

  def nro
    @nro
  end

Este método es indispensable para poder sumar los valores de ambos dados:

suma = dado1.nro + dado2.nro
puts "La suma de los dos dados es #{suma}"

Pero no podemos cambiar el valor de @nro desde fuera de la clase:

dado1.nro = 100

Con esto nos aseguramos que si el nro del dado es incorrecto (es decir que no almacena un valor entre 1 y 6) el problema se encuentra en la misma clase Dado y no fuera.

Para generar un valor aleatorio utilizamos el método rand (si le pasamos el valor 6 luego nos retorna un valor entre 0 y 5:

  def tirar
    @nro = rand(6) + 1
  end

Problema propuesto

  • Plantear una clase TablaMultiplicar. Definir un atributo que se le pueda indicar el valor de la tabla a mostrar, por defecto comienza en 2. Definir también un método que imprima 10 términos de la tabla.
Solución
ejercicio140.rb

class TablaMultiplicar

  def initialize
    @tabla = 2
  end

  def imprimir
    puts "Tabla del #{@tabla}"
    for x in 1..10
      valor = @tabla * x
      puts "#{x} * #{@tabla} = #{valor}"
    end
    puts "*" * 50
  end

  def tabla=(valor)
    @tabla = valor
  end

end


t = TablaMultiplicar.new
t.imprimir
t.tabla = 5
t.imprimir
t.tabla = 9
t.imprimir