Method Overriding in Java

In this article, we will learn about method overriding in java with the help of real-world examples.
If we define the method which we have already defined in Base Class, this is known as Method Overriding.

What is Method Overriding in Java?

Method Overriding in Java is a feature that allows the subclass or the child class to provide a unique implementation for a method, which you have already defined in one of its parent classes or superclass. A method is said to override the method of the super-class if the method in the subclass has the same parameters, the same name, and the same return type as the method present in one of its super-class or parent class. This process explained in the above lines is known as Method Overriding in Java.

Illustrative Examples to show Method Overriding in Java:

Code to demonstrate the Method Overriding in Java:

// Base Class
class Parent {
    void show(){
        System.out.println("Parent's show()");
    }
}

// Inherited class
class Child extends Parent {
    // This method overrides show() of Parent
    @Override
    void show()
    {
        System.out.println("Child's show()");
    }
}

// Driver class
class Main {
    public static void main(String[] args)
    {
        Parent obj1 = new Parent();
        obj1.show();

        Parent obj2 = new Child();
        obj2.show();
    }
}

Output:

Parent's show()
Child's show()

Explanation:
In the above example, we have declared a base class named “Parent”, and a subclass named “Child” which extends the class “Parent”. The Child class overrides the method show() of the Parent class. Now, in the main method if the Parent type references the Parent object, then Parent’s show is executed but if the Parent type references the Child object, then the Child’s show is executed. This process of execution of two different methods is known as Run Time Polymorphism.

Rules for Method Overriding in Java

1. Access Specifiers and Method Overriding in Java
The overriding method must not impose restrictions that go beyond the access level. Access restrictions may be laxer than for methods that are overridden.

For example, a protected instance method can be made public in the parent class (superclass), but it cannot be made private in the child class (subclass). An error will be produced at compile time if you try to make a child class private.

class Parent {
    // private methods are not overridden
    private void fun1(){
        System.out.println("From parent fun1()");
    }

    protected void fun2(){
        System.out.println("From parent fun2()");
    }
}

class Child extends Parent {
    // new fun1() method unique to Child class
    private void fun1(){
        System.out.println("From child fun1()");
    }

    // overriding method with more accessibility
    @Override
    public void fun2(){
        System.out.println("From child fun2()");
    }
}

// Driver class
class Main {
    public static void main(String[] args){
        Parent obj1 = new Parent();
        obj1.fun2();
        Parent obj2 = new Child();
        obj2.fun2();
    }
}

Output:

From parent fun2()
From child fun2()

Explanation:
In the above example code, we have defined a base class named Parent and a subclass named Child which overrides some methods present in the base class. Next we have called the same function fun2() and it provides two different outputs because of method overriding in java.

2. We cannot override the Final Methods in Java
We cannot perform Method overriding on the methods that are declared as Final. If we try to do so, it will give Compile Time Error.

class Parent {
    // Can't be overridden
    final void fun() {
        //Statements
    }
}

class Child extends Parent {
    // This would produce error
    void fun() {
        // Statements
    }
}

Output:

Main.java:10: error: fun() in Child cannot override fun() in Parent
    void fun() {
         ^
  overridden method is final

Explanation: In the above-shown example, since we try to Override the method fun(), it gives a Compilation Error because the function fun() is declared as final.

3. We cannot override methods declared as Static
A method marked as static cannot be overridden. When a static method with the same method signature as the superclass (parent class) is defined in the subclass (child class), it is known as Method Hiding.

If the static method is redefined by a derived class or a subclass, then it is not method overriding, but known as Method Hiding.

class Parent {
    static void fun1(){
        System.out.println("From parent " + "static fun1()");
    }

    void fun2(){
        System.out.println("From parent " + "non-static(instance) m2()");
    }
}

class Child extends Parent {
    static void fun1(){
        System.out.println("From child static fun1()");
    }

    @Override
    public void fun2(){
        System.out.println("From child " + "non-static(instance) fun2()");
    }
}

class Main {
    public static void main(String[] args)
    {
        Parent obj1 = new Child();
        obj1.fun1();
        obj1.fun2();
    }
}

Output:

From parent static fun1()
From child non-static(instance) fun2()

Explanation: In the above code, we have declared two methods fun1() and fun2() in base class. Since the fun1() is declared as static, so this method can’t be overridden by the method in the derived class, while fun2() being non-static gets override by the method in derived class.

4. We cannot perform Method overriding on Private Methods in Java
Due to the fact that they are bonded at compile time, private methods cannot be overridden. Therefore, even private methods of a subclass cannot be overridden.

class Parent {
    private void display() {
        System.out.println("parent method is executed");
    }
}

class Child extends Parent {
    private void display() {
        System.out.println("child method is executed");
    }
}

public class Main {
    public static void main(String args[]){
        Parent parentObject = new Parent(); 
        parentObject.display(); // this line when execute will throw compiler error
  
        Parent childObject = new Child(); 
        childObject.display(); // this line when execute will throw compiler error
    }
}

Output:

Main.java:16: error: display() has private access in Parent
        parentObject.display(); // this line when execute will throw compiler error
                    ^
Main.java:19: error: display() has private access in Parent
        childObject.display(); // this line when execute will throw compiler error
                   ^

Explanation: In the above code, since the method display() is declared as private. So it cannot be overridden and thus we get a compilation error when we compile the code.

5. The Overriding method must have the same return type as of method declared in the base class
The return type of the method must match the return type stated in the original overridden method in the superclass, or be a subtype of it.

Since Java 5.0, it is permissible to have a distinct return type for a method that is overridden in a child class, but the return type of the child should be a subtype of the return type of the parent. This phenomenon is known as Covariant Return Type.

class Alpha {
    Alpha doStuff(char c) {
        return new Alpha();
    }
}
class Beta extends Alpha { 
    Beta doStuff(char c) {  // legal override in Java 1.5
        return new Beta();
    }
} 

class Main{
    public static void main(String args[]){
        Alpha childObject = new Beta(); 
        childObject.doStuff('a'); 
    }
}

Explanation: The above code will run and will not give any compile time error because the return type of Beta() function is a subtype of the return type of the parent alpha() function.

6. We can also invoke the methods which are overridden
Using the super keyword makes we can call the overridden method’s superclass(Parent class) version.

class Parent {
    void display() {
        System.out.println("Parent method is executed");
    }
}

class Child extends Parent {
    @Override
    void display() {
        super.display();
        System.out.println("Child method is executed");
    }
}

public class Main {
    public static void main(String args[]){
        Parent childObject = new Child(); 
        childObject.display();
    }
}

Output:

Parent method is executed
Child method is executed

Explanation: In the above example, we have called the overridden methods by using the Super keyword. The line “super.display()” will execute the method defined in the base class.

7. We cannot Override a Constructor
In Java, we cannot override a constructor because the name of the base class and the derived class cannot be the same. And the Constructor name must be the same to that of the class.

8. Overriding and abstract method
In order to prevent compile-time errors, abstract methods in an interface or abstract class are designed to be overridden in derived concrete classes (classes with no abstract methods).

//Abstract class  
abstract class Parent{
  public abstract void display( int x, String j);
}

class Child extends Parent{
    @Override
    public void display( int x, String j ){ 
        System.out.println("child method is executed");
    }
}

class Main{
    public static void main(String args[]){
        Parent childObject = new Child(); 
        childObject.display(1, "Alive is Awesome"); 
    }
}

Output:

child method is executed

Explanation: In the above-coded example, we have an abstract class. The abstract class methods have been override java by the concrete class. And we get the desired output.

Usage of @Override Annotation in Override Java Code

According to Oracle docs,

@Override annotation informs the compiler that the element is meant to override an element declared in a superclass.

 // mark method as a superclass method
   // that has been overridden
   @Override 
   int overriddenMethod() { }

It is not compulsory to use @Override annotation but it is considered a good coding practice and makes code more readable and easy to follow.

Super Keyword in Override Java

Using the super keyword, we can invoke parent class methods in overriding methods. Knowing that we have overridden a method in a child class, we can call the overridden method using an object from the child class. As demonstrated in the example below, we can invoke the overridden method by using super:

class Parent {
    void display() {
        System.out.println("Parent method is executed");
    }
}

class Child extends Parent {
    @Override
    void display() {
        super.display();
        System.out.println("Child method is executed");
    }
}

public class Main {
    public static void main(String args[]){
        Parent childObject = new Child(); 
        childObject.display();
    }
}

Output:

Parent method is executed
Child method is executed

Explanation: In the above example, we have called the overridden methods by using the Super keyword. The line “super.display()” will execute the method defined in the base class.

Why you should use Method Overriding in Java?

As already mentioned, Java can provide run-time polymorphism by using the overridden methods. The polymorphism enables general classes to declare methods that will be shared by all of their descendants while allowing subclasses to define the specific implementation of any or all of those methods. So it is crucial to object-oriented programming. Java also uses overridden methods to implement the polymorphism principle of "one interface, multiple methods."

One of the most effective tools that object-oriented design uses to promote code reuse and resilience is Dynamic Method Dispatch. It is an incredibly powerful tool to have code libraries that can call methods on instances of new classes without having to recompile them and have a clear abstract interface

Overridden methods enable us to invoke methods from any of the derived classes, without even knowing the type of an object from a derived class

Method Overloading vs Method Overriding in Java

Method overloading and method overriding are two important concepts in Java that are used to achieve polymorphism and dynamic method binding.

Method overloading refers to the ability to have multiple methods with the same name but different parameter lists in the same class. This allows for the same method name to be used for different functionality based on the number or type of parameters passed.

Method overriding, on the other hand, refers to the ability to provide a new implementation of a method that is already provided by a superclass in a subclass. This allows for the subclass to have its own behavior while still maintaining the same method signature as the superclass.

The main difference between the two is that overloading is related to the number of arguments and the type of arguments and overloading is done within the same class, whereas overriding is related to the inheritance and overridden method must have the same method signature as the method in the superclass.

In general, method overloading is used to increase the readability and maintainability of the code by providing different methods with the same name but different functionality, while method overriding is used to create more specific subclasses that can have their own unique behavior while still maintaining the same method signature as the superclass.

Conclusion
In conclusion, method overriding in Java allows a subclass to provide a specific implementation of a method that is already provided by its superclass. This allows for polymorphism and dynamic method binding, where the correct method is called at runtime based on the actual type of the object. To override java a method, the subclass method must have the same method signature (name, return type, and parameter types) as the superclass method, and it must use the "@Override" annotation. Additionally, the subclass method must have the same or higher level of access as the superclass method (e.g. a protected method in the superclass can be overridden by a public method in the subclass).

It’s important to note that, when overriding a method, the subclass should use the "super" keyword to call the superclass method if necessary. Also, when overriding a method, it’s important to consider the effect of the "final" and "static" keywords on the superclass method. A final method cannot be overridden and a static method is associated with the class and not the object, so it cannot be overridden.

In general, method overriding in java is a powerful feature of object-oriented programming that allows for greater code reuse and flexibility. It helps to extend the functionality of a superclass and create more specific subclasses that can have their own unique behavior.

Leave a Reply

Your email address will not be published. Required fields are marked *