In the Java programming language, both overriding and overloading mean re-using method name, but they are quite different. This article provides some comparisons between these two techniques. For details about each, see the following articles:

For the comparison, the following table gives us the similarities and differences between overriding and overloading methods:

 

Overriding methods

Overloading methods

Usage context

A subclass re-implements methods inherited from a superclass.

Provide multiple versions of a method with different signatures.

Method name

Must be the same.

Arguments list

Must be the same.

Must change the arguments lists.

Return type

Must have the same return type,

May have different return types.

throws clause

Must not throw new or broader checked exceptions.

May throw different exceptions.

Access modifiers

Must not have more restrictive access modifiers.

May have different access modifiers.

Method invocation resolution

Which method to invoke is decided at runtime.

Which method to invoke is decided at compile time.

Constructors

Cannot be overridden.

Can be overloaded.

Allowed methods

Only inherited methods can be overridden.

No restriction.

Disallowed methods

Static and final methods cannot be overridden.

No restriction.

 

From the above table, we can see that the rules of overriding are more restrictive than overloading. Let’s see some examples. Suppose that we have this superclass - Animal:

public class Animal {
	protected void eat() {
		System.out.println("Animal eats");
	}
}
And a subclass - Dog:

public class Dog extends Animal {

	public Dog() {
		System.out.println("I am a general dog");
	}
	
	public Dog(String breed) {
		System.out.println("I am a dog of this kind: " + breed);
	}
	
	@Override
	public void eat() {
		System.out.println("Dog eats default food");
	}
	
	public void eat(String food) {
		System.out.println("Dog eats this food: " + food);
	}
}
Here, the Dog class has two overloaded constructors:

  • Dog(): creates an instance of a general dog.
  • Dog(String bread): creates an instance of a dog with the specified breed.
The Dog class also has two versions of eat() method which are both overriding and overloading, because:

  • The eat() method without arguments, overrides the one inherited from the superclass Animal. This method also overloads another eat() method below:
  • The eat(String food) method overloads both the eat() method in the same class and the one inherited from the Animal class.
 

Here is the testing code:

Animal anim = new Dog();
anim.eat();

Dog bulldog = new Dog("Bulldog");
bulldog.eat("Bones");


Output:

I am a general dog
Dog eats default food
I am a dog of this kind: Bulldog
Dog eats this food: Bones
Here, two overloaded constructors are invoked to create two different instances of the Dog class:

Animal anim = new Dog();
Dog bulldog = new Dog("Bulldog");
Consider the following statements:

Animal anim = new Dog();
anim.eat();
Here, we can see that which method to be invoked is decided at runtime, based on the actual object. The anim reference variable is of type Animal, but it points to the actual object Dog, thus the overriding version of eat() method in the Dog class is invoked:

Dog eats default food
Consider the following class:

public class AnimalRanch {

	public void raise(Animal anim) {
		System.out.println("Raises an animal");
	}
	
	public void raise(Dog dog) {
		System.out.println("Raises a dog");
	}
}
Here, the AnimalRanch class has two overloaded methods raise(), the first accepts an Animal and the second accepts a Dog. Now let’s see the following code:

AnimalRanch ranch = new AnimalRanch();
Animal anim = new Dog();
Dog bull = new Dog("Bull");

ranch.raise(anim);
ranch.raise(bull);
Guess which raise() method will be called? Well, because overloaded methods are decided at compile time, so the call ranch.raise(anim) will invoke the raise(Animal) method as the anim reference variable is declared as Animal, though its actual object type is Dog. The second call, ranch.raise(bull) will invoke the raise(Dog) method because the bull reference variable is declared as Dog. Thus the following output:

I am a general dog
I am a dog of this kind: Bull
Raises an animal
Raises a dog
 

Related Tutorials:


About the Author:

is certified Java programmer (SCJP and SCWCD). He began programming with Java back in the days of Java 1.4 and has been passionate about it ever since. You can connect with him on Facebook and watch his Java videos on YouTube.



Add comment