Method Overriding in Java | Rules & Example Programs - Scientech Easy

Method Overriding in Java | Rules & Example Programs

Method Overriding in Java


When the method of superclass is overridden in the subclass to provide more specific implementation, it is called method overriding in Java. In other words, When the superclass method has available to the subclass by default through inheritance and the subclass does not satisfy with superclass implementation then subclass is allowed redefining that method on its requirement. This process is called overriding in Java.

So, if you want to modify a method in any class, changing method is not a good idea. Instead of that we should extend that class and override that method in a subclass. The superclass method which is overridden is called overridden method. The subclass method which is overriding the superclass method is called overriding method

What is the need/purpose of Method overriding in Java?


Let's take a simple example program to understand the need for method overriding in Java.
Assume that a young couple wants to marry. They have fixed the date of engagement and marriage. For this, the program is given below.
Program source code 1:
    package overriding; public class Marry { void engagementDate(){ System.out.println("Engagement will be done on 23 Dec."); } // Overridden method. void marryDate(){ System.out.println("Marry will be on 25 Dec"); } }
But due to the Christmas day on 25 Dec, They want to change the date of marrying. So, what will you do? You will open the class and change date of marrying. It is worst practice in Java because as per the object-oriented concept, the best practice is that class should not open for modification.
So, If you want to add new functionality to the existing class or if you want to modify the existing functionality of the class, you should not disturb the existing class. You should always write the subclass of the existing class and add the new functionality in subclass like this.
    package overriding; public class Change extends Marry{ // Overriding method. void marrydate(){ System.out.println("Marry will be on 27 Dec"); } } public class MyClass { public static void main(String[] args) { Change obj=new Change(); obj.engagementDate(); obj.marrydate(); } }
    Output: Engagement will be done on 23 Dec. Marry will be on 27 Dec
In the above program, Change is implementing the method marryDate() with the same signature as the superclass Marry i.e marryDate() of class Change is overriding marryDate() of class Marry. Hope that you will have understood the need or purpose of method overriding by this program.
Key points: 
The subclass can be written for the following three reasons.
1. To add a new feature or properties. For example, if the student had properties like age and location but in future, we get a new requirement to add one more property address for a student, we should go for extending a class and add a property address in the subclass. 2. To override or change the existing functionality.
3. To inherit the existing functionality.

Features of Method overriding in Java


There are the following features of method overriding in Java.
1. Method overriding technique supports the runtime polymorphism.
2. It allows a subclass to provide its own implementation of the method which is already provided by the superclass.
3. Only the instance method can be overridden in Java.
4. An instance variable can never be overridden in Java.
5. The overriding method can not be more restrictive than the overridden method of the superclass.
6. Overriding concept is not applicable for private, final, static, and main method in Java.
7. Method overriding can be done by changing the covariant return type only.
8. Overriding method cannot throw any checked exception.

Method overriding rules in Java


When you are overriding superclass method in a subclass, you need to follow certain rules. They are as follows.
1. Subclass method name must be the same as superclass method name. 
2. The parameters of subclass method must be the same as superclass method parameters. i.e In overriding, method name and argument types must be matched. In other words, the method signature must be the same or matched.
3. Must be Is-A relationship (Inheritance).
4. Subclass method's return type must be the same as superclass method return type. But this rule is applicable until Java 1.4 version only. From Java 1.5 version onwards, covariant return types are also allowed.
5. Subclass method's access modifier must be same or higher than superclass method access modifier.
Method overriding in Java
Key points: 
While the overriding method, you can increase the visibility of the overriding method but cannot reduce it.
For example, If superclass method is protected, you can override as a public method in the subclass. Similarly, the default method of superclass can be overridden by default, protected, or public.

What is a @Override annotation in Java?


@Override is an annotation which is used by the compiler to check all the rules of overriding. 
If we do not write this annotation, the compiler will apply only three overriding rules such as
1. Superclass and subclass relation.
2. Method name same.
3. Parameters are the same.
But if we have written as @Override on subclass method, the compiler will apply all rules irrespective of above three points.
For example:
a. Without annotation 
    In superclass
        private void msg(){
           System.out.println("Hello");
        }
    In subclass
        private void msg(){
           System.out.println("Hi")
        }
    Compile time: ok
    Runtime: ok
  With annotation
  In superclass
     private void msg(){
       System.out.println("Hello");
       }
  In subclass
    @Override
     private void msg(){
       System.out.println("Hi");
     }
  Compile time: Error- private method cannot be overridden.
   Runtime: ok
 Key points:
@Override is just for readability. Means that if a developer left a company and new developer joins the company, he/she will easily understand that this method is overridden. So, he can modify easily in the future. At least he/she will understand that there is some relationship between the two methods.
Now let's see interesting practical example programs based on overriding.

Java Method Overriding Example Programs


Program source code 2:
    package overridingProgram; public class A { void m1(){ System.out.println("A-m1"); } // Overridden method. void m2(){ System.out.println("A-m2"); } } public class B extends A { // Overriding method. void m2(){ System.out.println("B-m2"); } // Newly defined method in class B void m3(){ System.out.println("B-m3"); } } public class MyTest { public static void main(String[] args) { A a=new A(); a.m1(); a.m2(); B b=new B(); b.m1(); b.m2(); b.m3(); A a1=new B(); a1.m1(); a1.m2(); } }
    Output: A-m1 A-m2 A-m1 B-m2 B-m3 A-m1 B-m2
Key points: 
In overriding, method resolution is always solved by JVM based on the runtime object. During runtime, the actual object is used for calling the method. In other words, you always check the reference variable is pointing to the objects of which class?
Explanation:
1. a.m1() will call the m1() method of class A because the reference variable 'a' is pointing the object of class A. Similarly, a.m2() will also call the m2() method of class A.

2. b.m1() will call m1() method of class B because m1() of class A is available by default to class B due to inheritance and the reference variable 'b' is pointing to the objects of class B.
Similarly, b.m2() will call m2() method of class B because 'b' is pointing to the objects of the class. b.m3() will call the method of class B.

3. A a=new B() tells that the reference variable 'a1' of class A is pointing to the objects of class B. i.e parent reference variable can hold the child class object. a1.m1() will call the m1() method of class B because it is available by default.
a1.m2() will call m2() method of class B because the reference variable a1 is pointing to the objects of class B.

Role of Compiler & JVM in Overriding


Role of compiler in overriding:
During the compile time in the above program (A a1), a1 is the reference variable of parent class A i.e a1 is parent type. So, the compiler will be gone to check that the m2 method is available or not. If it is available in the parent class, no problem. The code will be happily compiled.

Role of JVM in overriding: 
At runtime, JVM will check that the reference variable is pointing to the which class object? parent class object or child class object. If it is pointing to the parent class object and m2 method is available in the parent class, it will execute the m2 method of the parent class. 

But if it is pointing to the child class object, JVM will immediately check that in the child class, the m2 method is overriding or not. If it is not overriding in the child class, JVM will call the default parent m2 method available in the child class. Thus, the JVM will execute the parent method only. If the m2 is overriding in the child class, at the runtime, JVM will execute the child class method based on the runtime object (new B()). In the overriding method, the resolution is always based on the runtime object.
Program source code 3:
    package overridingProgram; public class College { public void collegeName(){ System.out.println("Name of my college is PIET "); } // Overridden method. void estYear(){ System.out.println("It was established in 1999"); } } package overridingProgram; public class MyCollege extends College { // Here we are increasing visibility the overriding method. protected void estYear(){ System.out.println("It was established in 2001"); } } package overridingProgram; public class Test { public static void main(String[] args) { MyCollege mc=new MyCollege(); mc.collegeName(); mc.estYear(); College c=new MyCollege(); c.estYear(); } }
    Output: Name of my college is PIET It was established in 2001 It was established in 2001
Program source code 4:
    package overridingProgram; public class X { public void m1(){ System.out.println("m1-X"); } } package overridingProgram; public class Y extends X{ // Here, we are reducing the visibility of the overriding method. So, It will generate compile time error. void m1() // Cannot reduce the visibility of the inherited method from X. { System.out.println("m1-Y"); } } package overridingProgram; public class XY { public static void main(String[] args) { Y y=new Y(); y.m1(); } }
    Output: Error: Unresolved compilation problem: Cannot reduce the visibility of the inherited method from X

Why method overriding is called as runtime polymorphism?


Let's consider the program source code 1. 
1. We have class A with m2- "A-m2" prints.
2. We have subclass B with m2- "B-m2" prints.
3. Client wrote the main method and in the main,
    a. A a1=new B();
    b. a1.m2();
    c. Above line is compiled as class A has m2().
    d. At runtime, we will get the output of m1 which is there at class B.
    e. As at compile time, we think m2 of class A will get called but at runtime m2 of class B got executed because, in method overriding, method resolution is always based on runtime object (new B()). Therefore, it is also called runtime polymorphism or dynamic polymorphism or late binding. 

Why cannot a private method be overridden?


You cannot override private method because, when superclass method is private that will not be visible to the subclass, whatever the methods you writing in the subclass will be treated as a new method but not an overridden method. Let's see an example program to understand it.
Program source code 5:
    package overridingProgram; public class X { private void m1(){ System.out.println("m1-X"); } } public class Y extends X{ } public class XY { public static void main(String[] args) { Y y=new Y(); y.m1(); // Compile time error because the method m1() from type X is not visible in class Y. } }

Can we override a static method? 


No, we cannot override a static method. We cannot also override a static method with an instance method because a static method is bound with class whereas an instance method is bound with an object.
Program source code 6:
    package overridingProgram; public class X { static void m1(){ System.out.println("m1-X"); } } public class Y extends X{ @Override static void m1() // Compile time error because the method m1() of type Y must override or implement a supertype method. { System.out.println("m1-Y"); } } public class XY { public static void main(String[] args) { Y y=new Y(); y.m1(); } }

Can we stop method overriding?


Yes, we can stop method overriding by declaring method as final. See example programs.
Program source code 7: 
    package overridingProgram; public class X { // Overridden method. void m1(){ System.out.println("m1-X"); } } public class Y extends X{ @Override final protected void m1() // By declaring method as final, we can stop overriding. { System.out.println("m1-Y"); } } public class XY extends Y{ @Override public void m1() // Cannot override the final method from Y. { System.out.println("m1-XY"); } public static void main(String[] args) { Y y=new Y(); y.m1(); } }

Use of Method overriding in Java


1. Method overriding is used to achieve the runtime polymorphism in Java.
2. It is used to change the existing functionality of the superclass method.

Final words 
Hope that this article has covered almost all important concepts of method overriding in Java with practical example programs in easy ways. We hope that you will have enjoyed this article. Please like and share.
Thanks for reading!