In this section, we will learn what the inheritance is and how it works in Ruby.
What is Inheritance in Ruby?
Inheritance is the idea of using the members (instance method and variables) of one class for another class!
This is especially useful when we have a set of methods and algorithms defined in the body of a class for example and now instead of copy those instructions and use them in other places, we can make the owner class to be inherited by other classes and so they can call the same method as if they were its owner and use it for their own purposes.
The concept of inheritance design is really simple! Just follow the article to the end and, after reading and running the examples, the entire idea of inheritance will click into place.
Related Terminology to Inheritance in Ruby:
When it comes to inheritance, there are a set of terminologies that you need to be aware of because developers use these words a lot.
Ruby Super Class (Base Class | Parent Class):
A super class or Base class or Parent class, these words refer to the class that is used for other classes to inherit its members and use it in their own classes.
Ruby Subclass (Child Class):
Subclass or Child class is a class that inherits from other classes and uses their members in its own class.
Ruby Inheritance Declaration Syntax:
This is the syntax on the way we use one class to inherit from another class:
class ChildClass < ParentClass #instructions of the class end
To make a class to inherit from another class, all we need to do is to put the Parent class in front of the Child class and separate them using the `<` symbol.
For example, in the syntax above, now the `ChildClass` has the access to the members of the `ParentClass`. This means if we create an object from the ChildClass, it will have the access to the instance methods of the ParentClass as well.
Example: Implementing inheritance in Ruby
class Parent def sayHi print "Hello from the parent class" end end class Child < Parent end child = Child.new child.sayHi
Hello from the parent class
How does inheritance work in Ruby?
In this example, the `Child` class is inheriting from the `Parent` class. This means now any object we create from the Child class will have the access to the Parent class’s instance methods.
That’s why after creating an object from this class we could call the sayHi method as `child.sayHi`.
Types of Inheritance in Ruby
There are multiple different types of inheritance in Ruby and now in this section we will explain them one by one.
1- Single Level Inheritance in Ruby
The first type of inheritance is called single level inheritance! The last example you saw above is an example of a single level inheritance.
The reason we call it single level is that there’s only one class that is inheriting from another class and the parent class here does not inherit from other classes.
Basically, there’s one child class and one parent class.
2- Multilevel Inheritance in Ruby
A multi-level inheritance is when we have multiple classes that each is inheriting from another one.
For example, let’s say we have three classes name: A, B, and C.
Here the class C is inheriting from the class B, but then the class B itself is inheriting from the class A.
Be aware that in such case, the class C will have the access to the members of both B and A classes.
This means if we create an object from the class C, the object has the access to the instance methods of both B and A classes.
Example: multilevel inheritance in Ruby
class A def say_hi_a puts "This message is coming from the class A" end end class B < A def say_hi_b puts "This message is coming from the class B" end end class C < B def say_hi_c puts "This message is coming from the class C" end end cObj = C.new cObj.say_hi_a cObj.say_hi_b cObj.say_hi_c
This message is coming from the class A This message is coming from the class B This message is coming from the class C
Here’s the order of execution when you call a method using an object that is created from a child class:
Your program will first check the body of the class that the object is created from (for example, let’s say the class C in our last example). Now, if it found the method in that class, then it will invoke the method and the execution will continue within the body of the method until the operation is complete.
But if the Child method (the one that the object is created from) didn’t have the method, then your program will check the immediate parent class (The class B for example) to see if that class has the specified method or not)! If that method had the specified method, then it will be invoked in order to complete the operation. But then if the immediate parent class didn’t have such method, then the next parent class in the chain of inheritance (if any) will be checked to see if that one has the specified method.
Basically, your program starts its search from the very child class up to the parent classes in the chain of the inheritance until it found the target method, and the moment it found one, the method will be invoked. But if the specified method wasn’t found even after searching the entire classes in the inheritance, then an error will return and your program will stop.
In our program, for example, the cObj object invoked the `say_hi_a` method! But we know that this method is not in the body of the C class. So our program continued searching for the method in the class B. But because this class also didn’t have the method, our program continued to the next parent class (the class A) to see if that one has the method or not. Now the program sees this method there and so it invoked the method and the operation completed.
Ruby Is-A Relationship in Inheritance
Note that when working with inheritance, you can’t inherit from any type of class just because it has a method that can solve your problem!
There’s a concept that is called “is-a” which you should use when want to choose a class as the parent of another class!
Here’s how the “is-a” work:
Using this concept, we check a class and say: “the class X is a Y class”
For example, let’s say there’s a class named “Animal” and another class named “Cat”. Now if for some reasons you’ve decided to make the Cat class to inherit from the Animal class, first and foremost run this sentence on these two classes as:
“A Cat object is an Animal”
Now if the sentence did make sense, you can use the inheritance here, but if don’t then you should not use inheritance here to solve your problem.
Note that the sentence above makes sense and it is fine to make a Cat class inherit from the Animal class! Because after all, a Cat object is an Animal!
But the opposite is not true though! Which means we can’t make an Animal class to inherit from a Cat class! Because an Animal may or may not be a Cat! It might be a Dog or Sheep or Donkey etc.
So as long as there’s a logic in the sentence above, go for the inheritance. Otherwise don’t!