Inheritance in Ruby
Fast recall
Quick revision
Core answer
class Child < Parent. The child receives accessible behaviour from its ancestor chain, may override a method, and can call the overridden implementation with super. Bare super forwards the current method's arguments and block; super() deliberately sends none. Use inheritance for a real substitutable 'is-a' relationship and modules or composition for reusable behaviour that is not one.Whether you know Ruby has single inheritance (one parent), super calls the parent, and is-a is the right test.
Using inheritance for code reuse alone (prefer composition/modules), or forgetting super passes args automatically.
Inheritance = subclass < superclass (Puppy < Dog). Single inheritance. super calls parent. is-a relationship. Prefer composition over deep trees.
Interview-ready guide
Interview answer
Inheritance lets one Ruby class reuse and specialise the behaviour of another. class Admin < User makes Admin a subclass of User. An Admin object can use User's instance methods unless Admin provides its own version. A Ruby class has one direct superclass, while modules can add more behaviour to its ancestor chain.
When Ruby receives admin.greeting, it looks for greeting from the most specific class through the ancestor chain. If Admin#greeting exists, it runs first. Calling super inside it continues that lookup and invokes the next matching implementation; it does not name a particular parent class.
The subclass can initialise its own state and still reuse the parent's work. Bare super forwards the current method's arguments and block. super() sends no arguments, while super(name) sends only the value written. The example uses the explicit form so the parent receives only name.
Use inheritance only when every child can safely stand in for the parent and keep the same contract. Reusing a few methods is not enough. If an object only needs one capability or helper, delegation or a module usually creates less coupling. Keep class hierarchies shallow and inspect Admin.ancestors when lookup is unclear.
Inheritance in Ruby
Direct Answer
Ruby supports single class inheritance with class Child < Parent. The child receives accessible behaviour from its ancestor chain, may override a method, and can call the overridden implementation with super. Bare super forwards the current method's arguments and block; super() deliberately sends none. Use inheritance for a real substitutable 'is-a' relationship and modules or composition for reusable behaviour that is not one.
Deep Dive & Architecture
Ruby does not copy parent methods into the subclass. When a message is sent, it searches the receiver's singleton class, its class, included or prepended modules in their lookup order, then superclasses and their ancestors. Admin.ancestors exposes the effective chain and is often the fastest way to explain which implementation will run.
Overriding places a method earlier in that search. super does not mean 'call a class named Parent'; it means 'continue searching for this method after the current owner'. That is why super also works cleanly with modules in the chain. Bare super preserves the current arguments and block, whereas super() is an explicit empty call.
Constructors are ordinary methods in this model. If a subclass defines initialize, the parent's initializer does not run automatically. The subclass calls super with the parent inputs, then establishes its own state. Missing that step often leaves inherited methods reading unset instance variables.
The design boundary is substitutability. A subclass should preserve what callers rely on: accepted inputs, meaningful outputs, and object invariants. If the child merely needs a helper service or one capability, composition and module inclusion avoid coupling its entire identity to a parent implementation.
Code Example
class User
def initialize(name)
@name = name
end
def greeting
"Hello #{@name}"
end
end
class Admin < User
def initialize(name, area)
super(name) # send the parent exactly one argument
@area = area
end
def greeting
"#{super} — admin for #{@area}"
end
end
Admin.new('Ravi', 'billing').greeting
# => 'Hello Ravi — admin for billing'
Admin.ancestors.first(2) # => [Admin, User]
Common Mistakes & Pitfalls
Using inheritance for code reuse alone (prefer composition/modules), or forgetting super passes args automatically.
Check your understanding
Answer these without looking back at the article.
- When would you use Inheritance in a real project?
- How would you compare Inheritance with an alternative?
- What is a common mistake when using Inheritance?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.