DEV Community

abbiecoghlan
abbiecoghlan

Posted on • Updated on

Class Inheritance VS Modules in Ruby

In Ruby, we can use either class inheritance or modules to provide shared functionality throughout a program. This post explores the difference between class inheritance and modules, and considerations to help determine the appropriate use of each.

Class Inheritance

Inheritance between classes in Ruby allows for the creation of classes that have access to shared methods while still maintaining distinct, unique classes. When one class, known as the child or subclass, is inherited from another class, known as the parent or “super” class, it is given access to all of the methods of the parent. For example, we might have a parent class “Dog”, with a child class of “Dalmatian”. In the code below, we define these classes without the use of inheritance.

class Dog

    def bark
        "Woof!"
    end

    def sleep
        "zzzzz"
    end

    def find_that_smell
        "sniff sniff sniff"
    end

end

class Dalmatian

    def bark
        "Woof!"
    end

    def sleep
        "zzzzz"
    end

    def find_that_smell
        "sniff sniff sniff"
    end

end  
Enter fullscreen mode Exit fullscreen mode

The acronym DRY stands for "don't repeat yourself", and it is an important principle in software design. In the code below, using class inheritance, we can get the same functionality as above, but we have the benefit of keeping our code DRY. Our Dalmatian class now has access to all of the behavior of the Dog class.

class Dog

    def bark
        "Woof!"
    end

    def sleep
        "zzzzz"
    end

    def find_that_smell
        "sniff sniff sniff"
    end

end

class Dalmatian < Dog

end  
Enter fullscreen mode Exit fullscreen mode

The use of inheritance allows us to share methods between classes in a way that reflects the real-world hierarchical relationship between our classes, and provides shared functionality accordingly. If a dog can bark, a Dalmatian can bark.

An important note about class inheritance when considering use is that, although you can inherit from a class that inherits from another class that inherits from yet another class- a single class can only inherit from one class at a time when it is defined.

Modules

Let's imagine we wanted to define an instance method that returns true if the animal is able to be housebroken. We could define this as an instance method within our dog class and have our individual dog breeds inherit the method. But what if our program had other animal classes, such as cats and rabbits, that we wanted to provide this method to as well?

class Animal 
end 

class Dog < Animal 
    def can_be_housebroken?
        true
    end 
end 

class Cat < Animal
    def can_be_housebroken?
        true
    end 
end 

class Rabbit < Animal 
    def can_be_housebroken?
        true
    end 
end 
Enter fullscreen mode Exit fullscreen mode

As you can see above, we would have to define those methods over and over again. Sometimes, as in this case, we might want to share functionality between classes that do not have a clear hierarchical arrangement. Instead of making a new class that is built from the blueprint of an existing class, like when we inherit, we may simply want to group methods together and make those methods available to a variety of other classes. Modules allow us to do just that.

Let’s use a module instead of class inheritance. First, we will define our module. Then, within the definition of our classes, we can use the keyword include along with the module name in any number of classes in which we would like to provide access to the functions we defined in our module.

module IndoorPet
    def can_be_housebroken?
        true
    end
end  

class Animal 
end 

class Dog < Animal 
    include IndoorPet
end 

class Cat < Animal
    include IndoorPet
end 

class Rabbit < Animal 
    include IndoorPet
end
Enter fullscreen mode Exit fullscreen mode

As you can see, the use of Modules provides a great solution for extending functionality and avoiding repetitive code in situations where there is no clear parent-child relationship. Once it is defined, a module can be included in many classes. There is also no limit to how many modules you can include in an individual class. One thing to keep in mind about modules when considering use is that, unlike with classes, you cannot have an instance of a module.

Class Inheritance vs Modules

Class inheritance and modules both allow us to extend functionality throughout our program while reducing repetitive code. When trying to figure out when to use modules vs class inheritance, some considerations include whether or not you need to create instances, whether or not there is a hierarchical relationship between classes, and how the extended functionality is related to the relationships between groups. If you are trying to build a class from the framework of an already defined class, you can use class inheritance to adopt the behaviors of a parent class. If you've created a group of methods that you’d like to use repeatedly throughout your program in many different classes that are not hierarchically related, you can use modules to provide your classes access to the methods defined within your modules.

In our next post, we dig deeper into modules in ruby, exploring the include, extend, and prepend keywords. You can read that post here.

Top comments (3)

Collapse
 
niyanta_zamindar_63b4bdbc profile image
Niyanta Zamindar

HI, in the example under Modules, why haven't you kept the method can_be_housebroken inside the Animal class so that when the other classes inherit from it they get the method? Instead of creating a module for it. I am not clear with use case here.

Collapse
 
prasoondavid profile image
Prasoon David

@Niyanta Interfaces or Module are used when there is no proper hierarchical relationship
Suppose you keep the method 'can_be_housebroken?' in Animal class,
and you create a childClass Lion from animal. Suppose Lion's house cant be broken , then the method 'can_be_housebroken?' will return true.

Collapse
 
aruna profile image
aruna-x

Clear and helpful. Thanks!