Menu
CoddyTech

Sobrescritura de métodos

Parte de la sección Programación orientada a objetos del Journey de Ruby de Coddy. Lección 23 de 57.

Una subclase puede redefinir un método definiendo uno con el mismo nombre. Ruby busca primero un método en la propia clase del objeto y solo después en la superclase, por lo que prevalece la versión de la subclase:

class Animal
  def speak
    "..."
  end
end

class Dog < Animal
  def speak
    "Woof"
  end
end

class Fish < Animal
end

puts Dog.new.speak
puts Fish.new.speak

Salida:

Woof
...

Un método de una superclase que llama a otro método usa la versión sobrescrita para los objetos de la subclase. El método compartido se escribe una vez, y cada subclase cambia solo la parte que difiere:

class Animal
  def initialize(name)
    @name = name
  end

  def introduce
    "#{@name} says #{speak}"
  end

  def speak
    "..."
  end
end

class Cat < Animal
  def speak
    "Meow"
  end
end

puts Cat.new("Tom").introduce
puts Animal.new("Thing").introduce

Salida:

Tom says Meow
Thing says ...

Anular to_s en una subclase cambia cómo se imprime solo esa subclase. Los métodos que no anula siguen heredándose de la superclase:

class Item
  def initialize(name, price)
    @name = name
    @price = price
  end

  def to_s
    format("%s %.2f", @name, @price)
  end
end

class SaleItem < Item
  def to_s
    format("%s %.2f (sale)", @name, @price * 0.8)
  end
end

puts Item.new("Lamp", 20)
puts SaleItem.new("Lamp", 20)

Salida:

Lamp 20.00
Lamp 16.00 (sale)

El orden en que Ruby busca son los ancestros de la clase: la propia clase, después su superclase, y así sucesivamente hasta Object. La primera clase de esa lista que define el método lo proporciona:

class Animal
  def speak
    "..."
  end
end

class Dog < Animal
  def speak
    "Woof"
  end
end

class Puppy < Dog
end

puts Puppy.new.speak
p Puppy.ancestors.take(3)

Salida:

Woof
[Puppy, Dog, Animal]
challenge icon

Desafío

Fácil

Completa las clases de nómina. Employee almacena un name y tiene pay(hours), que devuelve hours * 20, y payslip(hours), que devuelve Ada: 800 usando pay. Manager sobrescribe pay con un valor fijo de 1500, independientemente de las horas. Intern sobrescribe pay con hours * 12, pero como máximo 300. payslip solo está definido en Employee.

El código proporcionado lee líneas como employee Ada 40, manager Bo 50 o intern Cy 20, crea el objeto correspondiente e imprime su recibo de pago y, después, imprime el pago total.

Tu código va en employee.rb, manager.rb e intern.rb. main.rb contiene el código de entrada/salida proporcionado y no se puede editar.

Pruébalo tú mismo

require_relative 'employee'
require_relative 'manager'
require_relative 'intern'

# Código de entrada/salida proporcionado: déjalo tal como está
input = []
while (line = gets)
  input << line.chomp
end
kinds = { "employee" => Employee, "manager" => Manager, "intern" => Intern }
total = 0
input.each do |line|
  kind, name, hours = line.split
  worker = kinds[kind].new(name)
  puts worker.payslip(hours.to_i)
  total += worker.pay(hours.to_i)
end
puts "total: #{total}"
quiz iconPonte a prueba

Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.

Todas las lecciones de Programación orientada a objetos

Practica por tu cuenta: Compilador de Ruby online