🎓 A1Learner
🔍
0 of 34 lessons completed

Ruby Inheritance in Depth

The beginner course showed a child class taking methods from a parent class. This lesson goes deeper with super, which lets an override build on the parent version instead of replacing it.

An override adds a line first

Dog writes speak again and adds its own line. super then runs the speak method from Animal.

class Animal
  def speak
    puts "makes a sound"
  end
end
class Dog < Animal
  def speak
    puts "barks loudly"
    super
  end
end
dog = Dog.new
dog.speak

super() hands nothing up

The initialize in Animal takes no arguments. Dog calls super() with empty parentheses, then stores its own name.

class Animal
  attr_reader :kind
  def initialize
    @kind = "animal"
  end
end
class Dog < Animal
  attr_reader :name
  def initialize(name)
    super()
    @name = name
  end
end
dog = Dog.new("Rex")
puts dog.kind
puts dog.name

super hands a new value up

Captain receives a short name and hands a longer one up. The reader then shows the value the parent stored.

class Player
  attr_reader :name
  def initialize(name)
    @name = name
  end
end
class Captain < Player
  def initialize(name)
    super("#{name} (captain)")
  end
end
captain = Captain.new("Ana")
puts captain.name

Three levels pass a call up

Each describe method runs super first and then adds its own line. The printed lines arrive in family order.

class Creature
  def describe
    puts "a living thing"
  end
end
class Animal < Creature
  def describe
    super
    puts "and an animal"
  end
end
class Dog < Animal
  def describe
    super
    puts "and a dog"
  end
end
dog = Dog.new
dog.describe

Example

class Animal
  attr_reader :name
  def initialize(name)
    @name = name
  end
  def greet
    puts "#{@name} says hello"
  end
end
class Dog < Animal
  def initialize(name, breed)
    super(name)
    @breed = breed
  end
  def greet
    puts "#{@name} wags its tail"
    super
  end
  def profile
    puts "#{@name} is a #{@breed}"
  end
end
class Puppy < Dog
  def initialize(name)
    super(name, "mixed breed")
  end
end
puppy = Puppy.new("Coco")
puppy.greet
puppy.profile

Key points

  • An override can call super to run the parent version of the same method.
  • super() with empty parentheses hands no arguments to the parent.
  • super with values in parentheses hands those new values to the parent.
  • Bare super hands the parent the same arguments the method received.
  • A family of three classes can pass a call up one level at a time.

In this example, Puppy hands a name and a fixed breed to Dog, and Dog hands the name on to Animal. The greet call prints the Dog line first, then super runs the Animal line. profile reads the breed that Dog stored.

Note

Each super call moves exactly one step up the family.

Try it Yourself

Edit the code, then press Run.

Running is simulated

Exercise

What does super() do inside a method?