Java Tutorials: Overloading is compile-time binding
Most beginners in Java get confused between Overloading and Overriding. One should understand that overloading is compile-time binding whereas overriding is runtime binding.
Have a look at the following example. There are three classes - Base, Derived and Test. As the name indicates class Derived extends class Base. The class Test has two overloaded methods with name methodA, with parameters Base and Derived respectively.
What is the output?
If your answer is
For your surprise the answer is wrong. The actual output is
Surprised?
This is because overloading is compile-time binding. When the compiler sees the line t.methodA(d);
It checks the data type of 'd', which is declared as 'Base'. So it looks for the method, methodA(Base) and binds the call to this method and hence the result.
Let us look at another common problem. When the programmers think to override the 'equals', but endup really overloading the method, there by creating some unforeseen problems.
Have a look at the following code, and say whether the equals method and the hashCode are implemented in the correct way?
In the first go, anyone will say the equals method is implemented correctly.
It follows all the constraints for the 'equals' method, and also implements the 'hashCode()' method following the same contract. But, if you look closer, you fill notice that, the 'equals' method really overloads the Object.equals(Object) method, instead of over loading it.
To prove that this won't work, let me give a simple program. In the main method, we are creating two EqualsOverloadTest objects with the same id. The two objects are added into the Set. Then we are printing the size of the set.
public static void main(String[] args) {
EqualsOverloadTest first = new EqualsOverloadTest("123");
EqualsOverloadTest second =
new EqualsOverloadTest(new String("123"));
System.out.println(first.equals(second));
Set set = new HashSet();
set.add(first);
set.add(second);
System.out.println(set.size());
}
Summary:
Overloading is a static or compile-time binding and Overriding is dynamic or run-time binding.
Have a look at the following example. There are three classes - Base, Derived and Test. As the name indicates class Derived extends class Base. The class Test has two overloaded methods with name methodA, with parameters Base and Derived respectively.
class Base{
}
class Derived extends Base{
}
class Test{
public void methodA(Base b){
System.out.println("Test.methodA(Base)");
}
public void methodA(Derived b){
System.out.println("Test.methodA(Derived)");
}
public static void main(String []args){
Test t = new Test();
Base b = new Base();
Base d = new Derived();
t.methodA(b);
t.methodA(d);
}
}
What is the output?
If your answer is
Test.methodA(Base)
Test.methodA(Derived)
This is wrong
For your surprise the answer is wrong. The actual output is
Test.methodA(Base)
Test.methodA(Base)
Surprised?
This is because overloading is compile-time binding. When the compiler sees the line t.methodA(d);
It checks the data type of 'd', which is declared as 'Base'. So it looks for the method, methodA(Base) and binds the call to this method and hence the result.
Let us look at another common problem. When the programmers think to override the 'equals', but endup really overloading the method, there by creating some unforeseen problems.
Have a look at the following code, and say whether the equals method and the hashCode are implemented in the correct way?
public class EqualsOverloadTest {
String id;
public EqualsOverloadTest(String id){
this.id = id;
}
public boolean equals(EqualsOverloadTest other){
return (other!=null) && this.id.equals(other.id);
}
public int hashCode() {
return id.hashCode();
}
}
In the first go, anyone will say the equals method is implemented correctly.
It follows all the constraints for the 'equals' method, and also implements the 'hashCode()' method following the same contract. But, if you look closer, you fill notice that, the 'equals' method really overloads the Object.equals(Object) method, instead of over loading it.
To prove that this won't work, let me give a simple program. In the main method, we are creating two EqualsOverloadTest objects with the same id. The two objects are added into the Set. Then we are printing the size of the set.
public static void main(String[] args) {
EqualsOverloadTest first = new EqualsOverloadTest("123");
EqualsOverloadTest second =
new EqualsOverloadTest(new String("123"));
System.out.println(first.equals(second));
Set set = new HashSet();
set.add(first);
set.add(second);
System.out.println(set.size());
}
We will expect the size of the Set to be '1' since the two Objects are equal. But it will print as '2'.
This is because we didn't override the 'equals' method. Whereas the first check with the equals method returned true, because we called the method as equals(EqualsOverloadTest), hence the proper method was called. But withing the set, it called the method equals(Object), which is not implemented, so uses the Object.equals(Object), which really checks whether they both are same instance or not. Hence we get an unexpected behaviour.
Summary:
Overloading is a static or compile-time binding and Overriding is dynamic or run-time binding.
6 Comments:
I don't like the examples you are using. They are clear to me but not to someone who has never heard of overloading and overriding. The main idea behind what you are showing in your examples is that two Object instances with a different address can never be equal. So what about overloading and overriding?
Thanks Kristof Van Gils for your comment, I will try to improve on the examples.
But, in the first example, I have explained the problem, in a very simple way. The second example, I just wanted to point out, how a the problem will result in, if we didnt understand the difference between overloading and overriding.
Nice Aite
Beginner Java Tutorial
Cool article on Overloading and Overriding. 2nd example was too good
it's really helpful.
class Animal { }
class Dog extends Animal
{
public void eat(Animal c) {
System.out.println("animal eating");
}
public void eat(Dog c) {
System.out.println("dog eating");
}
}
public class UseAnimlas
{
public static void main (String [] args)
{
Dog d = new Dog();
d.eat(null);
}
}
what should be output and why?
Post a Comment
<< Home