Search code examples
rubyclassinheritanceinitializationsuper

Why do we use super in ruby when I can inherit without its use?


I have searched on here for an answer to this question and couldn't find what I was after (in exact terms) so I'm gonna be slightly greedy and ask for some of the communities time. I hope to make my question as applicable as possible.

So, some context, I've been struggling with the idea of classes, class variables and methods for the last week but over the last 2 days have made serious headways in my understanding. However now I am faced with inheritance and can't work out why super would be used when I can just inherit without using it.

For example:

class Animal 
   def initialize (type, breed, age)
     @type = type
     @breed = breed
     @age = age
   end
end

class Dog < Animal
end

class Cat < Animal
end

class Fish 
end

woof = Dog.new("dog", "shitzu", 12)
meow = Cat.new("cat", "tabby", 5)
fish = Fish.new("fish", "gold", 2)

Output:

=> #<Dog:0x00000001447680 @type="dog", @breed="shitzu", @age=12> 
=> #<Cat:0x0000000140c918 @type="cat", @breed="tabby", @age=5> 
ArgumentError: wrong number of arguments (given 3, expected 0)

As you can see, I have been able to inherit from Animal on both my Dog and Cat classes, which I marked for inheritance, but on my Fish I have not been able to, because I didn't inherit.

If someone could explain why we use super, and point out flaws in my understanding, I'd be very grateful, I understand that I may be completely just misunderstanding usage here, but I'd like to just get it clarified. Thanks for your time, appreciate the help.


Solution

  • Using super lets a class override a method that it inherits from its parent and customize it.

    For instance, in your example, Dog and Cat inherit #initialize from Animal - but what if we wanted some special logic for Dog?

    class Dog < Animal
      def initialize(type, breed, age)
        raise "Sorry, dogs don't live that long!" if age > 100
    
        # Everything looks good - let Animal#initialize run now
        super
      end
    end
    

    This lets Dog customize what its initialize method does, but still call through to the original inherited method.