Para hacer algunos ejemplos de herencia, métodos y atributos de clase vamos a modelar un sistema de nómina para una compañía.
Empezamos con una clase Employee
de la cual van a extender otras clases:
class Employee
attr_reader :name, :email, :salary
def initialize(attrs)
@name = attrs[:name]
@email = attrs[:email]
@password = attrs[:password]
@salary = attrs[:salary]
end
def validate_password
password.length >= 5 && password.length <= 40
end
end
Acá es importante mencionar que podríamos haber recibido múltiples argumentos en el initialize
, pero cuando son más de dos argumentos es mejor utilizar un hash:
e1 = Employee.new(name: "Pedro", email: "[email protected]", password: "test1234", salary: 200)
Hay dos tipos de empleados: Manager
y Worker
. Los dos extienden de Employee
. El ejercicio es primero definirlos:
class Manager < Employee
def initialize(attrs={})
super(attrs) # también es posible copiar lo del padre pero es mejor así
end
end
class Worker < Employee
def initialize(attrs={})
super(attrs)
end
end
Un ejercicio adicional es instanciar un Manager
y un Worker
y mostrar la clase de cada uno (se les dice que con el método class
pueden obtener la clase):
m1 = Manager.new
puts m1.class # Manager
w1 = Worker.new
puts w1.class # Worker
Los Woker
s tienen un atributo adicional hours
que inicia en 0 y que representa el número de horas que han trabajado y un método work
que reciba un parámetro con el número de horas que se deben sumar:
class Worker < Employee
attr_reader :hours
def initialize(attrs)
super(attrs)
@hours = 0
end
def work(hours)
@hours += hours
end
end
Los Manager
s tienen unos Worker
s a su cargo y deben tener un método report
que devuelve el número de horas totales trabajadas por sus Worker
s:
class Manager < Employee
attr_reader :workers
def initialize(attrs)
super(attrs)
@workers = attrs[:workers]
end
def report
total = 0
@workers.each do |worker|
total += worker.hours
end
total
end
end
Driver code, esto se les puede mostrar para que vean cómo se va a utilizar:
pedro = Worker.new(name: "Pedro", email: "[email protected]", password: "test1234", salary: 200)
juan = Worker.new(name: "Juan", email: "[email protected]", password: "test1234", salary: 200)
joshua = Manager.new(name: "Joshua", email: "[email protected]", password: "test1234", salary: 1000, workers: [pedro, juan])
pedro.work(10)
juan.work(20)
pedro.work(10)
puts "Los trabajadores de Joshua trabajaron #{joshua.report} horas"
El siguiente ejercicio es modificar Employee
para cargar una lista de employees:
def Employee
def self.find_all
pedro = Worker.new(name: "Pedro", email: "[email protected]", password: "test1234", salary: 200)
juan = Worker.new(name: "Juan", email: "[email protected]", password: "test1234", salary: 200)
joshua = Manager.new(name: "Joshua", email: "[email protected]", password: "test1234", salary: 1000, workers: [pedro, juan])
[pedro, juan, joshua]
end
end
employees = Employee.find_all
employees.each do |e|
text = "El empleado #{e.name} es un #{e.class}"
if e.is_a? Manager
text += " y su grupo ha trabajado #{e.report} horas"
elsif e.is_a? Worker
text += " y ha trabajado #{e.hours} horas"
end
end