Java Override and Overload
Override
Override is the process where a subclass rewrites the implementation of a method that is accessible from its parent class, with the condition that the return value and parameters remain unchanged. The shell remains the same, but the core is rewritten!
The benefit of overriding is that the subclass can define its own behavior as needed. This means the subclass can implement a method from the parent class according to its needs.
An overridden method cannot throw new checked exceptions or broader exceptions than those declared by the overridden method. For example: If a method in the parent class declares a checked exception IOException, the overridden method cannot throw Exception as Exception is a superclass of IOException, but it can throw IOException or a subclass of IOException.
In the principles of object-oriented programming, overriding allows any existing method to be overridden. Here is an example:
TestDog.java File Code:
class Animal{
public void move(){
System.out.println("Animals can move");
}
}
class Dog extends Animal{
public void move(){
System.out.println("Dogs can run and walk");
}
}
public class TestDog{
public static void main(String args[]){
Animal a = new Animal(); // Animal object
Animal b = new Dog(); // Dog object
a.move(); // Executes the method in Animal class
b.move(); // Executes the method in Dog class
}
}
The above example compiles and runs with the following result:
Animals can move
Dogs can run and walk
In the example above, even though b is of type Animal, it executes the move method of the Dog class.
This is because during the compilation phase, only the reference type is checked.
However, at runtime, the Java Virtual Machine (JVM) specifies the type of the object and executes the method of that object.
Therefore, the above example compiles successfully because the move method exists in the Animal class, but at runtime, the method of the specific object is executed.
Consider the following example:
TestDog.java File Code:
class Animal{
public void move(){
System.out.println("Animals can move");
}
}
class Dog extends Animal{
public void move(){
System.out.println("Dogs can run and walk");
}
public void bark(){
System.out.println("Dogs can bark");
}
}
public class TestDog{
public static void main(String args[]){
Animal a = new Animal(); // Animal object
Animal b = new Dog(); // Dog object
a.move(); // Executes the method in Animal class
b.move(); // Executes the method in Dog class
b.bark();
}
}
The above example compiles and runs with the following result:
TestDog.java:30: cannot find symbol
symbol : method bark()
location: class Animal
b.bark();
^
The program will throw a compile-time error because the reference type Animal does not have the bark method.
Rules for Method Overriding
The parameter list of the overriding method must be exactly the same as that of the method being overridden.
The return type can be different from that of the overridden method, but it must be a derived class of the return type of the overridden method (in Java 5 and earlier, the return type must be the same; from Java 7 onwards, it can be different).
The access level cannot be more restrictive than that of the overridden method. For example: If a method in the parent class is declared as public, it cannot be declared as protected in the subclass.
A member method in a parent class can only be overridden by its subclass.
Methods declared as final cannot be overridden.
Methods declared as static cannot be overridden but can be redeclared.
If the subclass and the parent class are in the same package, the subclass can override all methods except those declared as private and final.
If the subclass and the parent class are not in the same package, the subclass can only override methods declared as public and protected that are not final. The method overriding can throw any unchecked exception, regardless of whether the overridden method throws an exception or not. However, the overriding method cannot throw new or broader checked exceptions. Conversely, it can reduce or remove the exceptions thrown by the overridden method.
-
Constructors cannot be overridden.
-
If a class cannot be inherited, its methods cannot be overridden.
Usage of the Super Keyword
When it is necessary to invoke the overridden method of the parent class in a subclass, the super keyword should be used.
TestDog.java File Code:
class Animal{
public void move(){
System.out.println("Animals can move");
}
}
class Dog extends Animal{
public void move(){
super.move(); // Invokes the superclass method
System.out.println("Dogs can run and walk");
}
}
public class TestDog{
public static void main(String args[]){
Animal b = new Dog(); // Dog object
b.move(); // Executes the Dog class method
}
}
The above example compiles and runs with the following result:
Animals can move
Dogs can run and walk
Overloading
Overloading occurs within a class when methods have the same name but different parameters. The return types can be the same or different.
Each overloaded method (or constructor) must have a unique list of parameter types.
The most common place for overloading is the constructor.
Overloading Rules:
The overloaded method must change the parameter list (different number or types of parameters).
The overloaded method can change the return type.
The overloaded method can change the access modifier.
The overloaded method can declare new or broader checked exceptions.
Methods can be overloaded within the same class or in a subclass.
The return type cannot be used as a distinguishing feature for overloaded methods.
Example
Overloading.java File Code:
public class Overloading {
public int test(){
System.out.println("test1");
return 1;
}
public void test(int a){
System.out.println("test2");
}
// The following two have different parameter order
public String test(int a,String s){
System.out.println("test3");
return "returntest3";
}
public String test(String s,int a){
System.out.println("test4");
return "returntest4";
}
public static void main(String[] args){
Overloading o = new Overloading();
System.out.println(o.test());
o.test(1);
System.out.println(o.test(1,"test3"));
System.out.println(o.test("test4",1));
}
}
Differences Between Overriding and Overloading
Aspect | Overloaded Method | Overridden Method |
---|---|---|
Parameter List | Must be changed | Must not be changed |
Return Type | Can be changed | Must not be changed |
Exceptions | Can be changed | Can be reduced or removed, must not throw new or broader exceptions |
Access | Can be changed | Must not be more restrictive (can be less restrictive) |
Summary
Method overriding and overloading are different manifestations of polymorphism in Java. Overriding represents polymorphism between a parent and a subclass, while overloading is a specific form of polymorphism within a class.
(1) Method overloading occurs when a class defines multiple methods with the same name but different parameters (different number or types of parameters).
(2) Method overriding occurs when a subclass has a method with the same name, parameters, and return type as a method in its parent class.
(3) Method overloading is a form of polymorphism within a class, whereas method overriding is a form of polymorphism between a subclass and its parent class.