What is the difference between override and overload?
Overloading of methods is a compiler trick to allow you to use the same name to perform different actions depending on parameters.
Overriding a method means that its entire functionality is being replaced. Overriding is something done in a child class to a method defined in a parent class.
Overload - similar signature - same name, different parameters
void foo() {
/** overload */
}
void foo( int a ) {
/** overload */
}
int foo() {
/** this is NOT overloading, signature is for compiler SAME like void foo() */
}
Override - you can redefine method body when you inherit it.
class A {
void foo() {
/** definition A */
}
}
class B extends A {
void foo() {
/** definition B, this definition will be used when you have instance of B */
}
}
Overloading :
public Bar foo(int some);
public Bar foo(int some, boolean x); // Same method name, different signature.
Overriding :
public Bar foo(int some); // Defined in some class A
public Bar foo(int some); // Same method name and signature. Defined in subclass of A.
If the second method was not defined it would have inherited the first method. Now it will be replaced by the second method in the subclass of A.
Overloading: picking a method signature at compile time based on the number and type of the arguments specified
Overriding: picking a method implementation at execution time based on the actual type of the target object (as opposed to the compile-time type of the expression)
For example:
class Base
{
void foo(int x)
{
System.out.println("Base.foo(int)");
}
void foo(double d)
{
System.out.println("Base.foo(double)");
}
}
class Child : Base
{
@Override void foo (int x)
{
System.out.println("Child.foo(int)");
}
}
...
Base b = new Child();
b.foo(10); // Prints Child.foo(int)
b.foo(5.0); // Prints Base.foo(double)
Both calls are examples of overloading. There are two methods called foo
, and the compiler determines which signature to call.
The first call is an example of overriding. The compiler picks the signature "foo(int)" but then at execution time, the type of the target object determines that the implementation to use should be the one in Child
.
Override
Is when a method which is inherited by a subclass from a superclass is replaced (overridden) in the subclass.
class A {
void foo() {
/** definition A of foo */
}
}
class B extends A {
void foo() {
/** definition B of foo */
}
}
Now if you call foo
using:
A a = new B();
a.foo();
The B
definition of foo
will be run. This is not so intuitive since you will get a compile error if the class A
didn't have a method called foo
. So the type of the object a
which is A
has to have the method foo
, then you can call it, and the method foo
of the instance will be executed, which is that of class B
, hence 'execution time'.
Overload
When you create a method with the same name as an existing method. To avoid a compile time error, you have to define the new method with different parameters than the existing one. This way the methods will be distinguishable. Have a method with the same name and parameters, but a different return type is still vague and will therefore cause a compile error. Example of overloading:
class A {
void bar(int i) {}
// The following method is overloading the method bar
void bar(Object a) {}
// The following will cause a compile error.
// Parameters should differ for valid overload
boolean bar(int i) {
return true;
}
}
On interesting thing to mention:
public static doSomething(Collection<?> c) {
// do something
}
public static doSomething(ArrayList<?> l) {
// do something
}
public static void main(String[] args) {
Collection<String> c = new ArrayList<String> ();
doSomething(c); // which method get's called?
}
One would suppose the method with the ArrayList argument would be called but it doesn't. The first method is called since the proper method is selected at compile time.