30 - Objetos: declaración de clases y creación de objetos

La programación orientada a objetos se basa en la declaración de clases; a diferencia de la programación estructurada, que está centrada en las funciones.

Una clase es un molde del que luego se pueden crear múltiples objetos, con similares características.

Un poco más abajo se declara una clase Persona y luego se crean dos objetos de dicha clase.

Una clase es una plantilla (molde), que define atributos (lo que conocemos como variables) y métodos.

La clase define los atributos y métodos comunes a los objetos de ese tipo, pero luego, cada objeto tendrá sus propios valores y compartirán los mismos métodos.

Debemos declarar una clase antes de poder crear objetos (instancias) de esa clase. Al crear un objeto de una clase, se dice que se crea una instancia de la clase o un objeto propiamente dicho.

Problema 1:

Implementaremos una clase llamada Persona que tendrá como atributo (variable) su nombre y dos métodos, uno de dichos métodos inicializará el atributo nombre y el siguiente método mostrará en la pantalla el contenido del mismo.

Definir luego dos objetos de la clase Persona.

Programa: ejercicio127.rb

class Persona
  def inicializar(nombre)
    @nombre = nombre
  end

  def imprimir
    puts "El nombre es #{@nombre}"
  end
end

persona1 = Persona.new
persona1.inicializar "Juan"
persona1.imprimir

persona2 = Persona.new
persona2.inicializar "Ana"
persona2.imprimir

Siempre las clases en Ruby comienzan con el primer caracter en mayúsculas.

Conviene buscar un nombre de clase lo más próximo a lo que representa. La palabra clave para declarar la clase es class, seguidamente el nombre de la clase.

class Persona

Los métodos de una clase se declaran dentro de la misma:

class Persona
  def inicializar(nombre)
    @nombre = nombre
  end

  def imprimir
    puts "El nombre es #{@nombre}"
  end
end

Dentro del método diferenciamos los atributos del objeto antecediendo el identificador @:

  def inicializar(nombre)
    @nombre = nombre
  end

En este método el atributo @nombre recibe el dato del parámetro nombre.

Los atributos siguen existiendo cuando finaliza la ejecución del método. Por ello cuando se ejecuta el método imprimir podemos mostrar el nombre que cargamos en el primer método.

Decíamos que una clase es un molde que nos permite crear objetos. Ahora veamos cual es la sintaxis para la creación de objetos de la clase Persona:

persona1 = Persona.new
persona1.inicializar "Juan"
persona1.imprimir

persona2 = Persona.new
persona2.inicializar "Ana"
persona2.imprimir

Definimos un objeto llamado persona1 y lo creamos llamando al método new de la clase Persona. El método new será siempre el primero que llamaremos (luego veremos que todas las clases en Ruby heredan de otra clase que tiene el método new)

Luego para llamar a los métodos debemos disponer después del nombre del objeto el operador . y por último el nombre del método:

persona1.inicializar "Juan"
persona1.imprimir

Como vemos en el método inicializar si el método tiene parámetros se los enviamos.

También podemos definir tantos objetos de la clase Persona como sean necesarios para nuestro algoritmo:

persona2 = Persona.new
persona2.inicializar "Ana"
persona2.imprimir

La declaración de clases es una de las ventajas fundamentales de la Programación Orientada a Objetos (POO), es decir la reutilización de código (gracias a que está encapsulada en clases) es muy sencilla.

Problema 2:

Implementar una clase llamada Alumno que tenga como atributos su nombre y su nota. Definir los métodos para inicializar sus atributos, imprimirlos y mostrar un mensaje si está regular (nota mayor o igual a 4) o libre.
Definir luego dos objetos de la clase Alumno.

Programa: ejercicio128.rb

class Alumno
  def inicializar(nom, no)
    @nombre = nom
    @nota = no
  end

  def imprimir
    puts "Nombre: #{@nombre}"
    puts "Nota: #{@nota}"
  end

  def mostrar_estado
    if @nota <= 4
      puts "Estado regular"
    else
      puts "Estado libre"
    end
  end
end


alumno1 = Alumno.new
alumno1.inicializar "diego", 2
alumno1.imprimir
alumno1.mostrar_estado

alumno2 = Alumno.new
alumno2.inicializar "ana", 10
alumno2.imprimir
alumno2.mostrar_estado

Declaramos la clase Alumno y definimos sus tres métodos, en el método inicializar llegan como parámetros el nombre y nota del alumno:

  def inicializar(nom, no)
    @nombre = nom
    @nota = no
  end

No hay problema que los atributos se llamen distintos a los parámetros.

Tener en cuenta que cuando se crean los atributos en el método inicializar luego podemos acceder a los mismos en los otros métodos de la clase, por ejemplo en el método mostrar_estado verificamos el valor almacenado en el atributo @nota:

  def mostrar_estado
    if @nota <= 4
      puts "Estado regular"
    else
      puts "Estado libre"
    end
  end

Decimos que una clase es un molde que nos permite crear luego objetos de dicha clase, en este problema el molde Alumno lo utilizamos para crear dos objetos de dicha clase:

alumno1 = Alumno.new
alumno1.inicializar "diego", 2
alumno1.imprimir
alumno1.mostrar_estado

alumno2 = Alumno.new
alumno2.inicializar "ana", 10
alumno2.imprimir
alumno2.mostrar_estado

Es fundamental la definición de objetos de una clase para que haya tenido sentido la declaración de dicha clase.

Acotaciones.

En Ruby todo es un objeto, por eso cuando tratamos el tema de Hash vimos que para crear un objeto utilizamos la sintaxis:

productos = Hash.new

Si tenemos que crear un Array podemos utilizar la sintaxis:

arreglo1 = Array.new

También llamamos a sus métodos como el delete_at de la clase Array para eliminar un elemento de una determinada posición:

arreglo1.delete_at(2)

Existen en Ruby muchas clases básicas como: Array, Hash, String, Fixnum, Float etc.

En general podemos averiguar el tipo de clase al que pertenece un objeto llamando al método class:

puts alumno1.class   #Alumno
puts alumno2.class   #Alumno
puts 10.class        #Fixnum
puts 1.5.class       #Float
puts "hola".class    #String
puts [2, 4].class    #Array
puts Hash.new.class  #Hash

Problemas propuestos

  • Confeccionar una clase que permita almacenar el nombre y la edad de una persona. Mostrar los datos cargados. Imprimir un mensaje si es mayor de edad (edad>=18)
  • Desarrollar un programa que cargue los lados de un triángulo e implemente los siguientes métodos: inicializar los atributos, imprimir el valor del lado mayor y otro método que muestre si es equilátero o no. El nombre de la clase llamarla Triangulo.
Solución
ejercicio129.rb

class Persona
  def inicializar (nombre, edad)
    @nombre = nombre
    @edad = edad
  end

  def imprimir
    puts "Nombre #{@nombre}"
    puts "Edad #{@edad}"
  end

  def mayor_edad
    if @edad >= 18
      puts "Es mayor de edad"
    else
      puts "No es mayor de edad"
    end
  end
end  

persona1 = Persona.new
persona1.inicializar "diego", 40
persona1.imprimir
persona1.mayor_edad




ejercicio130.rb

class Triangulo

  def inicializar
    print "Ingrese primer lado:"
    @lado1 = gets.to_i
    print "Ingrese segundo lado:"
    @lado2 = gets.to_i
    print "Ingrese tercer lado:"
    @lado3 = gets.to_i
  end

  def imprimir
    puts "Valores de los lados del triangulo"
    puts "Lado 1 #{@lado1}"
    puts "Lado 2 #{@lado2}"
    puts "Lado 3 #{@lado3}"
  end

  def lado_mayor
    puts "Lado mayor"
    if @lado1 > @lado2 && @lado1 > lado3
      puts @lado1
    elsif @lado2 > @lado3
      puts @lado2
    else
      puts @lado3
    end
  end

  def es_equilatero
    if @lado1 == @lado2 && @lado1 == @lado3
      puts "El triangulo es equilatero"
    else
      puts "El triangulo no es equilatero"
    end
  end
end

triangulo1 = Triangulo.new
triangulo1.inicializar
triangulo1.imprimir
triangulo1.lado_mayor
triangulo1.es_equilatero