Menu
Coddy logo textTech

Sobrescrita de métodos

Parte da seção Programação orientada a objetos do Journey de Ruby da Coddy. Lição 23 de 57.

Uma subclasse pode substituir um método definindo um com o mesmo nome. Ruby procura primeiro um método na própria classe do objeto e só depois na superclasse, portanto a versão da subclasse vence:

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

Saída:

Woof
...

Um método da superclasse que chama outro método usa a versão sobrescrita para objetos da subclasse. O método compartilhado é escrito uma vez, e cada subclasse altera apenas a parte que difere:

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

Saída:

Tom says Meow
Thing says ...

Sobrescrever to_s em uma subclasse altera a forma como somente essa subclasse imprime. Os métodos que ela não sobrescreve ainda vêm da superclasse:

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)

Saída:

Lamp 20.00
Lamp 16.00 (sale)

A ordem em que Ruby pesquisa é a dos ancestrais da classe: a própria classe, depois sua superclasse e assim por diante até Object. A primeira classe dessa lista que define o método fornece sua implementação:

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)

Saída:

Woof
[Puppy, Dog, Animal]
challenge icon

Desafio

Fácil

Complete as classes de folha de pagamento. Employee armazena um name e possui pay(hours), que retorna hours * 20, e payslip(hours), que retorna Ada: 800 usando pay. Manager sobrescreve pay com um valor fixo de 1500, independentemente das horas. Intern sobrescreve pay com hours * 12, mas no máximo 300. payslip é definido apenas em Employee.

O código fornecido lê linhas como employee Ada 40, manager Bo 50 ou intern Cy 20, cria o objeto correspondente e imprime seu contracheque; em seguida, imprime o pagamento total.

Seu código deve ficar em employee.rb, manager.rb e intern.rb. main.rb contém o código fornecido de entrada/saída e não pode ser editado.

Experimente você mesmo

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

# Código de entrada/saída fornecido: mantenha-o 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 iconTeste seus conhecimentos

Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.

Todas as lições de Programação orientada a objetos

Pratique por conta própria: Compilador de Ruby online