Get free ebooK with 50 must do coding Question for Product Based Companies solved
Fill the details & get ebook over email
Thank You!
We have sent the Ebook on 50 Must Do Coding Questions for Product Based Companies Solved over your email. All the best!

Method Overriding in Java

Last Updated on August 18, 2023 by Mayank Dham

One of the fundamental concepts that elevates Java’s object-oriented paradigm is method overriding. This powerful technique empowers developers to extend and customize the behavior of their classes, creating more flexible and expressive codebases.
Method overriding in Java allows a subclass to provide its own implementation for a method that is already defined in its superclass. This inheritance mechanism not only enhances code reusability but also enables the creation of intricate class hierarchies with specialized behaviors. Whether you’re a Java novice or an experienced developer seeking a deeper understanding, this article dives into the nuances of method overriding, shedding light on its syntax, rules, benefits, and real-world applications.

What is Method Overriding in Java?

Method overriding is a Java feature that allows a subclass or child class to provide a unique implementation for a method that has already been defined in one of its parent classes or superclass. A method is said to override the method of the super-class if it has the same parameters, name, and return type as the method present in one of its super-classes or parent classes. s explained in the above lines, this 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

Method overriding in Java allows a subclass to offer a customized implementation of a method that is already given by its superclass. This enables polymorphism and dynamic method binding, in which the right method is invoked at runtime based on the actual type of the object. To override a method in Java, the subclass method must have the same method signature (name, return type, and parameter types) as the superclass method and must utilize the "@Override" annotation. Furthermore, the subclass method must have the same or higher degree of access as the superclass method (e.g., a protected method in the superclass can be overridden by a public method in the subclass).In general, method overriding in Java is a strong feature of object-oriented programming that allows for increased code reuse and flexibility. It aids in extending the functionality of a superclass and creating more particular subclasses with their own distinct behaviors.

Frequently Asked Questions (FAQs) related to Method Overriding in Java:

Q1: What is Method Overriding in Java?
Answer: Method overriding is a concept in object-oriented programming where a subclass provides a specific implementation for a method that is already defined in its superclass. This allows a subclass to customize or extend the behavior of methods inherited from its superclass.

Q2: How is Method Overriding Different from Method Overloading?
Answer: No, method overriding and method overloading are distinct concepts. Method overloading involves defining multiple methods in the same class with the same name but different parameters. Method overriding, on the other hand, occurs when a subclass provides a new implementation for a method inherited from its superclass.

Q3: Can the Access Modifier Change During Method Overriding?
Answer: No, you cannot reduce the visibility of the overridden method in the subclass. The access modifier of the overriding method must be the same or less restrictive than the access modifier of the overridden method. This ensures that the subclass doesn’t restrict access to the method in a way that the superclass did not.

Q4: How Does the @Override Annotation Work?
Answer: While not strictly necessary, the @Override annotation is a good practice. When you use @Override, the compiler checks whether the method you’re intending to override actually exists in the superclass. This helps catch typos and other mistakes that might lead to unintentional method creation. It’s a helpful tool to ensure that your overriding is accurate and follows the intended structure.

Q5: Can Method Overriding Involve a Change in Return Type?
Answer: No, the return type of an overridden method must remain the same or be a covariant type (subtype) of the return type in the superclass. This ensures that the subclass’s method is substitutable for the superclass’s method in all contexts. Covariant return types were introduced in Java 5 to allow more flexible method overriding in terms of return types.

Leave a Reply

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