Core Java coding questions frequently asked in written tests and interviews - part 3: method overloading Vs overriding
Core Java Coding Questions and Answers for beginner to intermediate level
Q1 | Q2 | Q3 | Q4 | Q5 - Q8 | Q9 | Q10 | Q11 | Q12 - Q14 | Q15 |
This part of the Java coding interview question is on the popular method overloading versus overriding concept.
Q. What will be the output of the following code snippet?
public class MethodOverrideVsOverload { public boolean equals( MethodOverrideVsOverload other ) { System.out.println("MethodOverrideVsOverload equals method reached" ); return true; } public static void main(String[] args) { Object o1 = new MethodOverrideVsOverload(); Object o2 = new MethodOverrideVsOverload(); MethodOverrideVsOverload o3 = new MethodOverrideVsOverload(); MethodOverrideVsOverload o4 = new MethodOverrideVsOverload(); if(o1.equals(o2)){ System.out.println("objects o1 and o2 are equal"); } if(o3.equals(o4)){ System.out.println("objects o3 and o4 are equal"); } } }A. The output will be
MethodOverrideVsOverload equals method reached objects o3 and o4 are equal
What concepts does this question try to test?
- In Java, a class can only extend a single class (i.e. single inheritance), and when it does not explicitly extend a class, it implicitly extends the class Object. So, MethodOverrideVsOverload implicitly extends the class Object.
- The majority of the non final Object class methods are meant to be overridden by the sub classes.
public boolean equals(Object obj); // make note of this method public int hashCode(); public String toString();
- The method overloading takes place at compile time (i.e. static binding) and method overriding takes place at runtime (i.e. dynamic binding). Static binding means the JVM decides, which class or method to call during compile time. Dynamic binding means, the JVM decides, which class or method to call during runtime. The polymorphism is possible because of dynamic binding. Learn more about compile-time vs runtime.
- The method overriding must adhere to the following rules
Arguments Must not change. Return type Can't change except for covariant (subtype) returns. Exceptions The extending class can eliminate or call fewer exceptions than its parent, but must not throw new or broader checked exceptions. Access Must not be more restrictive than the class it extends. Can be less restrictive. Invocation Which method to call is based on object type, at runtime time (i.e. dynamic binding).
Now, if you look at the above code
The "equals(MethodOverrideVsOverload other)" method in class MethodOverrideVsOverload does not actually override the Object class's "public boolean equals(Object obj)" method. This is because it fails to adhere to the "Arguments" rule as both methods have different arguments as one is of type "MethodOverrideVsOverload " and the other of type "Object" . So, the two methods are overloaded (happens at compile time) and not overridden.
So, when o1.equals(o2) is invoked, the public boolean equals(Object obj) method of the object class is invoked because during compile time, the o1 and o2 are of type Object.The Object class's equals( ... ) method returns false as it compares the memory address (e.g. Object@235f56 and Object@653af32) of both objects.
When o3.equals(o4) is invoked, the "equals( MethodOverrideVsOverload other )" of the class MethodOverrideVsOverload is invoked as during compile time o3 and o4 are of type MethodOverrideVsOverload, hence you get the above output.
What follow on questions can you expect?
Q. How will you fix the above issue?
A. In Java 5, annotations were introduced and one of the handy compile time annotations is the @override, which will ensure that the methods are overridden correctly. If you had this annotation, when you override it incorrectly as in the above example, a compile time error will be thrown.
So, to fix it, add the @override annotation to the "boolean equals( MethodOverrideVsOverload other )" of the MethodOverrideVsOverload class. This will give you a compile time error indicating that the method is not properly overridden. Now, fix the method signature by changing the argument type in the method signature from "MethodOverrideVsOverload" to "Object" as shown below.
So, when o1.equals(o2) is invoked, the public boolean equals(Object obj) method of the object class is invoked because during compile time, the o1 and o2 are of type Object.The Object class's equals( ... ) method returns false as it compares the memory address (e.g. Object@235f56 and Object@653af32) of both objects.
When o3.equals(o4) is invoked, the "equals( MethodOverrideVsOverload other )" of the class MethodOverrideVsOverload is invoked as during compile time o3 and o4 are of type MethodOverrideVsOverload, hence you get the above output.
What follow on questions can you expect?
Q. How will you fix the above issue?
A. In Java 5, annotations were introduced and one of the handy compile time annotations is the @override, which will ensure that the methods are overridden correctly. If you had this annotation, when you override it incorrectly as in the above example, a compile time error will be thrown.
So, to fix it, add the @override annotation to the "boolean equals( MethodOverrideVsOverload other )" of the MethodOverrideVsOverload class. This will give you a compile time error indicating that the method is not properly overridden. Now, fix the method signature by changing the argument type in the method signature from "MethodOverrideVsOverload" to "Object" as shown below.
public class MethodOverrideVsOverload { @Override public boolean equals( Object other ) { System.out.println("MethodOverrideVsOverload equals method reached" ); return true; } public static void main(String[] args) { Object o1 = new MethodOverrideVsOverload(); //during compile time o1 is of type Object //during runtime o1 is of type MethodOverrideVsOverload Object o2 = new MethodOverrideVsOverload(); //during compile time o2 is of type Object //during runtime o2 is of type MethodOverrideVsOverload MethodOverrideVsOverload o3 = new MethodOverrideVsOverload(); //o3 is of type MethodOverrideVsOverload // during both compile time and runtime MethodOverrideVsOverload o4 = new MethodOverrideVsOverload(); //o4 is of type MethodOverrideVsOverload // during both compile time and runtime if(o1.equals(o2)){ System.out.println("objects o1 and o2 are equal"); } if(o3.equals(o4)){ System.out.println("objects o3 and o4 are equal"); } } }
The output will be
MethodOverrideVsOverload equals method reached objects o1 and o2 are equal MethodOverrideVsOverload equals method reached objects o3 and o4 are equal
This is because now the methods are overridden and this happens at runtime. This is a bit tricky question, and think out loud at the interview to show that you understand the fundamentals.
Labels: Core Java
31 Comments:
Excellent explanation!
Funda Clear
So nicely exlplained,damn good
Very nice example !!!
OMG that's awesome :)
Very Well Explained, gr8 :)
great example
The compile time(overloading) and run time(Runtime) binding was clear!
Thanq so much for posting such useful explanations
Excellent answer.Thanks
Thank you so much.
Awesome...
I understood very well..
What a clear explanation!
Excellent question, and excellent explanation...
Really awesome..
Got more confidence on funda
awesome explanation
You r simply superb.. :)
very well thought of............splendid work!!!
Thats really very good explanation. Would like some more of this sort. Thanks a lot.
good explanation
really very good example.............
Nicely explained....!
Nice one
found the grail here
very good explanation
In the revised example when for object 03 and 04 equals method is called.Their object type is of methodoverloadvsmethodoverride then how this call didnt give error..Is it not wrong parameter?
very good
Man you are a Gem....Excellent work love u. from sashikanta mallick(bangalore)
Very clear explanation.
No its not wrong parameter, as methodoverloadvsmethodoverride passes IS-A relationship. means methodoverloadvsmethodoverride IS-A Object (Parent-Child behavior).
superb
v. nice explaination
Superb Explaination!
nice
Post a Comment
Subscribe to Post Comments [Atom]
<< Home