Menu
Coddy logo textTech

Overriding Methods

Part of the Object Oriented Programming section of Coddy's Ruby journey. Lesson 23 of 57.

A subclass can override a method by defining one with the same name. Ruby looks for a method in the object's own class first and only then in the superclass, so the subclass's version wins:

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

Output:

Woof
...

A superclass method that calls another method uses the overridden version for subclass objects. The shared method is written once, and each subclass changes only the part that differs:

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

Output:

Tom says Meow
Thing says ...

Overriding to_s in a subclass changes how only that subclass prints. Methods it does not override still come from the superclass:

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)

Output:

Lamp 20.00
Lamp 16.00 (sale)

The order Ruby searches is the class's ancestors: the class itself, then its superclass, and so on up to Object. The first class in that list that defines the method provides it:

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)

Output:

Woof
[Puppy, Dog, Animal]
challenge icon

Challenge

Easy

Complete the payroll classes. Employee stores a name and has pay(hours), which returns hours * 20, and payslip(hours), which returns Ada: 800 using pay. Manager overrides pay with a fixed 1500 whatever the hours. Intern overrides pay with hours * 12, but at most 300. payslip is defined only in Employee.

The supplied code reads lines employee Ada 40, manager Bo 50 or intern Cy 20, creates the matching object and prints its payslip, then prints the total pay.

Your code goes in employee.rb, manager.rb and intern.rb. main.rb holds the supplied input/output code and cannot be edited.

Try it yourself

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

# Supplied input/output code: keep it as it is
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 iconTest yourself

This lesson includes a short quiz. Start the lesson to answer it and track your progress.

All lessons in Object Oriented Programming

Practice on your own: Online Ruby compiler