Is the initialize method really necessary?
Before answering that question, let's refresh what an initialize
method really
is.
In Object Oriented Programming terminology, initialize
method is a
constructor.
And a constructor is a method that is executed automatically on
instantiation.
Constructors exists in other Object Oriented Programming languages like C++,
Java, JavaScript also. But they might use different names, it won't be
initialize
.
So initialize
method is the method that's called automatically on
instantiation.
i.e. if you run the following code:
So what if we don't define an initialize
method, would it throw an error?
Let's create another class Article
and see what happens.
The above code ran successfully without any errors.
From this, its pretty clear that the use of initialize
method is optional.
Inheritance is tricky
What do you think would happen if you were to run the following code?
The code will throw an ArgumentError
.
But why so?
The reason is that, on instantiating a child class, the parent class is also
instantiated.
And that requires passing the author
argument to the parent class.
One thing to note here is that, if we had defined even an empty initialize
method within Article
class, then the above script would work. We will discuss
about this case in the upcoming sections.
The super method
To solve the above issue we must pass the author
argument to the parent class.
This is where the super
method comes into play.
We could pass the arguments to the initialize
method of the parent class by
calling the super
method with the required arguments. i.e.
Or even better, invoke the super
method without any arguments and parentheses.
Both will give the same following output.
Note: You have be very careful when invoking the super
without the
arguments and parentheses.
The reason is that, such invocations directly passes the arguments from the
child class to the parent class as positional arguments.
i.e. The following two code snippets are equivalent to each other.
This would work even with the following modification:
Notice the parameter names are different in the Document
and Article
classes.
Still the code would work perfectly, giving the output:
The equivalent code for the above snippet is:
So what's the problem? If you look at the previous code, the equivalent version,
you will notice that writer
and publication_month
were passed as positional
arguments to the super
.
Therefore, if you switch the positions of the parameters in the Article
class
definition, you will not get the expected result. i.e.
The above code will give you:
Note: The super
method is not just used to invoke the initialize
method
of the parent class. When you invoke the super
, you are actually invoking the
method, in the parent class, with the same name as the method from which you are
invoking the super
.
For example:
The above code would output:
And if there's no corresponding method in the parent class, the invocation of
super
will throw a NoMethodError
. See the following example.
Wow, that was a lot of information.
Take a deep breath and let it out. Take some time and go through it again if you
wish. Once you feel that you are thorough with what you have learnt till now,
continue reading.
It's a marathon not a sprint.
If you are caught up till now, you might be wondering - Should we invoke the
super
method in the initialize
method if we don't have to pass the
arguments? Before getting to the answer, keep this following point in your mind.
If we don't define the initialize
method, the child class will invoke the
super
by itself.
As in, the following two snippets are equivalent to each other.
That is, both the following code snippets are equivalent to each other.
Even the initialize
method is optional in this case.
And both the code snippets would give the exact same result.
But this is not the case if you define the initialize
method and you skip the
super
invocation.
The following section will describe why.
Pitfalls of the super method
If you define the initialize
method and don't invoke the super
method, then
the initialize
method of the parent class is not invoked.
ie. If you run this code:
The output wouldn't print the string in the initialize
method of the parent
class, as shown in the following snippet.
Therefore, in order to invoke the initialize
method of the parent class, you
must always invoke the super
method in your child class's constructor.
Conclusion
- If inheritance is involved and you need to define the
initialize
method of
the child class, then you should always invoke the super
method.
So the correct way to implement the previous snippet is:
- And the
initialize
method is optional if no arguments are to be passed to
the parent class.