Java @Override – Overriding in Java

Filed Under: Java

Overriding is a very popular concept in programming languages. Method overriding in Java is the case where we have the same method present in the superclass as well as the subclass. It’s one of the OOPS Concepts to implement runtime polymorphism in Java.

Overriding in Java

Let’s see how we normally override a method in java.


package com.journaldev.annotations;

public class BaseClass {
    
    public void doSomething(String str){
        System.out.println("Base impl:"+str);
    }
    
}

Now we will create a subclass overriding BaseClass doSomething method.


package com.journaldev.annotations;

public class ChildClass extends BaseClass{

   public void doSomething(String str){
       System.out.println("Child impl:"+str);
   }

}

Now let’s create a test class to check how overriding works in java.


package com.journaldev.annotations;

public class OverrideTest {

    public static void main(String[] args) {
        BaseClass bc = new ChildClass();
        bc.doSomething("override");
    }

}

Output of the above program is:


Child impl:override
Method Overriding In Java

Method Overriding In Java

How Java Overriding Works?

  • The method signature must be exactly the same in the superclass and the subclass.
  • When the instance is created, subclass constructor must be used.
  • At the compile time, the variable refers to the superclass. However, in runtime, it refers to the subclass object.
  • When the method is called on the variable, it looks like the superclass method will be called. But the method is present in the subclass object, hence it’s called.

Here “bc” is of type BaseClass but at runtime, it’s the object of ChildClass. So when we invoke its doSomething(String str) method, it looks for the method in ChildClass and hence the output.

Will Java Override work with different method signature?

Now let’s change the BaseClass doSomething method like below.


//Change argument from String to Object
public void doSomething(Object str){
    System.out.println("Base impl:"+str);
}

You will notice that compiler won’t throw any warnings/errors and now if you run the test program output will be;


Base impl:override

The reason is that BaseClass doSomething(Object str) method is not anymore overridden by the ChildClass. Hence it’s invoking BaseClass implementation. ChildClass is overloading the doSomething() method in this case because the method name is the same but the method signature is different.

Java @Override Annotation

Java 1.5 introduced annotations. Java @Override annotation is one of the default java annotation. When we use this annotation for a method, it tells the compiler that we are trying to override a superclass method.

If you uncomment the @Override annotation in ChildClass, you will get following compile-time error message:

The method doSomething(String) of type ChildClass must override or implement a supertype method

java @Override annotation, Overriding in java

Java @Override annotation benefits

  • Java @Override annotation will make sure any superclass changes in method signature will result in a compile-time error and you will have to do necessary changes to make sure the classes work as expected.
  • It’s better to resolve potential issues at compile time than runtime. So always use java @Override annotation whenever you are trying to override a superclass method.

Overriding vs Overloading

Overriding Overloading
Overriding happens between superclass and subclass Overloading is present in the same class
The method signature must be the same in superclass and subclass. The method name must be the same but method signature must be different.
Identification of the method to be called happens at runtime. We can identify the method to be called at compile-time.
If overriding breaks, it can have adverse effects because the program will compile and run. However, the method from superclass will be called rather than subclass. If we change method name to break overloading, the error will come at compile time. So it’s easy to fix and don’t cause much harm.
Overriding is also called Runtime Polymorphism. Overloading is called as Compile-time Polymorphism.

Summary

Overriding in Java is very popular and you can find many examples in JDK itself. It’s mostly present where we have a base class with default implementation of the method and then the subclass overriding it and implementing it.

You can checkout more core java examples from our GitHub Repository.

Reference: Oracle Documentation

Comments

  1. Alex says:

    Even with no @Override no errors introduced… Why?) IntelliJ 2019.1

    1. Pankaj says:

      It’s best practice to use @Override annotation, not mandatory to use it.

  2. Jac says:

    Hi Pankaj,
    As per the rules of Java the most specific implementation is selected in case of overloading but in this case when we are passing String object, it is still calling base class method. Since the method present in subclass is most specific why is it calling super class method?

    1. Pankaj says:

      I believe you are talking about when we change the base class method argument to Object. In this case, the function with Object argument is not present in the child class, hence the Base Class method is invoked. What you are thinking of is also true but that will happen if the methods are present in the same class. You can quickly write a few functions to test it out.

  3. Ziyi says:

    Ummm… I didn’t get the error message, after I change to Object in BaseClass everything just works the same with/without the @Override….

  4. Jan Egil Kristiansen says:

    I got the message.

    But you have a typo, reminding me that I like to resolve potential issues at ‘rumtime’.

    1. Pankaj says:

      Thanks for noticing and comment, I have corrected it.

  5. Mohammad says:

    Thank you very much for informative notes..

  6. Siby says:

    Nicely explained..Simple yet very useful!!!

  7. Shelly says:

    Hi Pankaj,

    You have combined the clarification of overloading with the inheritance concept which is slightly confusing.As per this example many of the guys will assume that for overloading extending of class is necessary whereas this is not the case.Guys we can have the concept of overloading without inheritance too.Now you can explore it it would be interesting

    1. Pankaj says:

      Its overriding, not overloading.

      1. Eduard says:

        I have to agree that its confusing, first i didn’t understood neither why [ bc.doSomething(“override”) ] uses the base class method with the signature [ public void doSomething(Object str) ] instead of the child class (the instantiated object)’s “overloading” method with the signature [ public void doSomething(String str) ] since it accept a formal parameter of type String the same type passed in the test code (object of type String).

        That is the confusing part, albeit for me, as i’m still a beginner in Java ..

        Then after looking a the code a few more times i’ve noticed the way bc is instantiated [ BaseClass bc = new ChildClass(); ] and kind of understand that the BaseClass method takes precedence since Sting is an Object and it uses the interface of BaseClass even if the object is of ChildClass ( is this a form of type casting ? ) but then again, why does it call ChildClass.doSomething(String) method when used with @Override since the object bc was suposed to use the BaseClass interface ?

        Yeah Pankaj, this is a little confusing but even so, i still like the way you insert a little more complexity in your examples and in doing so you explain a little more that the original topic of the article like special cases or gotchas.

Leave a Reply

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

close
Generic selectors
Exact matches only
Search in title
Search in content
Search in posts
Search in pages