Skip to content
Inheritance Basics
step 1/7

Reading — step 1 of 7

Learn

~2 min readClasses, Inheritance, Modules

Ruby is single-inheritance for classes. Combined with modules (next lesson), the language gets multiple-inheritance-like behavior without the diamond problem.

Defining a subclass

class Animal
  def initialize(name)
    @name = name
  end
  
  def speak
    "#{@name} makes a sound"
  end
end

class Dog < Animal
  def speak
    "#{@name} barks"
  end
end

puts Dog.new("Rex").speak       # Rex barks
puts Animal.new("Cat").speak    # Cat makes a sound

< is the inheritance operator. Dog < Animal reads "Dog inherits from Animal."

The subclass can override methods (just redefine them) and inherit any not overridden.

super — calling the parent

Use super inside an overriding method:

class Dog < Animal
  def initialize(name, breed)
    super(name)              # calls Animal#initialize(name)
    @breed = breed
  end
  
  def speak
    super + " (#{@breed})"   # parent's speak + extra info
  end
end

Three forms:

  • super (no parens) — passes ALL the same args you received
  • super() (empty parens) — passes nothing
  • super(x, y) — explicit args

The distinction matters: bare super is a common idiom. super() is needed when the parent method takes no args but you don't want to forward yours.

Method lookup

When you call dog.speak, Ruby looks in:

  1. Dog
  2. Animal
  3. Object
  4. Kernel
  5. BasicObject

First match wins. The Dog.ancestors array shows the exact list:

Dog.ancestors      # [Dog, Animal, Object, Kernel, BasicObject]

Useful for debugging "why is this method behaving like this?"

Built-in inheritance

Every Ruby class implicitly inherits from Object:

class Empty
end

puts Empty.new.class            # Empty
puts Empty.superclass           # Object
puts Empty.new.respond_to?(:to_s)    # true (from Object)

That's why every object has class, to_s, inspect, nil?, ==, etc.

Visibility — public, private, protected

class Account
  def deposit(amount)
    update(amount)              # OK to call private
  end
  
  private
  
  def update(amount)
    @balance += amount
  end
end

a = Account.new
a.deposit(100)                  # OK
a.update(50)                    # ERROR — private
  • public (default) — anyone can call
  • private — only this object can call (no self.method, no other-object obj.method)
  • protected — this class and subclasses can call between instances

Common mistakes

  • Forgetting super in initialize — parent's setup doesn't run, instance variables uninitialized.
  • super vs super() — bare super passes args; super() passes none. Different behavior.
  • Multiple inheritance via class — Ruby doesn't allow it. Use modules.
  • Reopening a class accidentallyclass Foo either creates OR re-opens. If a class with that name already exists, you're modifying it.
  • Calling private with self.method — fails. Inside the class, just method. Private means you literally cannot use a receiver.

Discussion

Ask a question, share an insight, or help someone who’s stuck.

Sign in to post a comment or reply.

Loading…