Method Overloading v/s Method Overriding
Overview
In this post we'll see the subtle differences between method overloading and method overriding. We'll also look at the rules for doing overloading and overriding.
Method overloading
In a class when we define multiple functions with same name but different argument list, it's called method overloading. For example:
1int add(int a, int b) {
2 int add(int a, int b) {
3
4 return a + b;
5}
6float add(float a, float b) {
7
8 return a + b;
9}
10double add(double a, int b) {
11
12 return a + b;
13}
14double add(int a, double b) {
15
16 return a + b;
17}
add
. All these four functions have different argument list, (int, int), (float, float), (double, int) and (int, double) respectively. This is a classic example of method overloading. You can see many overloads of this kind in Java Math class. Here are some rules for method overloading:
Rule 1
You cannot only change the return type. The following is not a valid overload:
1int add(int a, int b) {
2 int add(int a, int b) {
3
4 return a + b;
5}
6
7//invalid overload
8float add(int a, int b) {
9
10 return a + b;
11}
Rule 2
As long as the argument list is different, return type can be anything.
1int add(int a, int b) {
2 int add(int a, int b) {
3
4 return a + b;
5}
6
7int add(float a, float b) {
8
9 return a + b;
10}
11
12double add(int a, float b) {
13
14 return a + b;
15}
Rule 3
As long as the argument list is different, access type of the method can be anything
1public int add(int a, int b) {
2 int add(int a, int b) {
3
4 return a + b;
5}
6
7private int add(float a, float b) {
8
9 return a + b;
10}
11
12protected double add(int a, float b) {
13
14 return a + b;
15}
Method Overriding
When a subclass provides an implementation of a method that is already defined in it's parent class, it's called method overriding.
1class Shape {
2
3 public void rotate() {
4
5 System.out.println("Shape's rotate");
6 }
7}
8
9class Square extends Shape {
10
11 public void rotate() {
12
13 System.out.println("Square's rotate");
14 }
15}
Rule 1
The argument list of must be same and return types must be compatible. It means that the overriding method (or the one in subclass) should have the same argument list as that of overridden method (the one in superclass).
Also the overriding method should have a compatible return type (i.e. either same or anything less) with overridden method. Let's look at an example:
1class Shape {
2
3 public int func1(int) {}
4
5 public double func2(int) {}
6
7 public int func3(int) {}
8}
9
10class Square extends Shape {
11
12 // valid override of func1()
13 public int func1(int) {}
14
15 //this is not an override
16 public int func1() {}
17
18 // valid override of func2()
19 public int func2(int) {}
20
21 // invalid override of func3()
22 public double func3(int) {}
23}
- public int func1(int) {} is a valid override of func1() as the argument list is same.
- public int func1() {} is not an override of func1() as the argument list is not same. (Will this cause error?)
- public int func2(int) {} is a valid override of func2() as the return type of this method (int) is compatible with it's parent (double). Compatible means either same or anything less (as int is less than double so it's compatible)
- public double func3(int) {} is an invalid override of func3() as the return type of this method (double) is not compatible with it's parent (int) as double is greater than int
Hope this particular rule is clear after all these examples.
Rule 2
Overriding method cannot be less accessible than overridden method. This rule is actually very simple. It says that the overriding method cannot have a lesser access modifier than it's counterpart. Let' see an example:
1class Shape {
2
3 public int func1(int) {}
4
5 private double func2(int) {}
6}
7
8class Square extends Shape {
9
10 // valid override of func1()
11 public int func1(int) {}
12
13 // invalid override of func1()
14 private int func1(int) {}
15
16 // valid override of func2()
17 private double func2(int) {}
18
19 // valid override of func2()
20 public double func2(int) {}
21}
- private int func1(int) {} is invalid because we've reduced the access of func1() from public (which was in parent) to private which is not correct
- public double func2(int) {} is valid because we are actually increasing the access of func2() from private to public
That concludes method overloading and overriding.
Acknowledgements
- Head First Java