A Guide to Method Overriding in Java with Examples

In our previous article, we learned about the inheritance feature of Object-Oriented Programming, where a subclass or a child class inherits the properties of the superclass or the parent class. In this way, the subclass will have access to all of the variables and methods of the superclass unless they are private.

But now, what if the subclass also defines a method present in the superclass. Then we can say that the subclass has overridden the superclass method, known as the method overriding.

Method overriding can only happen if an IS-A relationship exists between two entities (between classes, interfaces, or between a class and an interface ). We will discuss the method overriding a lot more, but first, we should understand the reference variables.

Reference variables

The only way to access an object is through a reference variable.

String str  = new String ("hi") /* Here "str" is a reference variable of type "String" */

So, we should know about a few points regarding reference variables.

  • A reference variable can be of any type, but once declared, that type can never be changed.
String str = new String("hi")
Integer str = 1 /* this wil throw error as we can't change the type of an already reference variable */

  • A reference variable can be reassigned to other objects. Like we can point the “str” reference variable to another string object by doing str = new String(“codekru”). Now, str points to a different string object named “codekru“.
String str = new String("hi")
str = new String("codekru") /* now, str will point to "codekru" string  */

  • A reference variable can refer to any object of the same or subclass type.
class Base {

}

class Derived extends Base {

}

public class Codekru {

      public static void main(String[] args) {

	Base base1 = new Base(); /* this is correct as reference variable
                                  can refer to the object of its own type */

	Base base2 = new Derived(); /* this is correct as reference variable can
                                       refer to the object of its subclass type also */

	Derived derived1 = new Derived(); /*  this is also correct */

	Derived derived2 = new Base(); /* this is wrong as reference variable cannot
                                       refer to the object of its superclass type */
	

     }
}

  • A reference variable’s type determines the methods invoked on the object.
class Base {

	public void display() {
		System.out.println("Display in base class");
	}

}

class Derived extends Base {

}

public class Codekru {

	public static void main(String[] args) {

		Base b = new Derived(); /* now "b" reference variable will only be able
					  to call the methods present in the "Base" class */

	}
}

Now, as we have an understanding of the reference variables, let’s now have a look at the method overriding.

Method overriding is overriding the methods of a base class within a derived class. Below is an example demonstrating how we can override the methods.

Code Example 1

Here, the Derived class will override the method present in the Base class.

class Base {

	public void display() {
		System.out.println("Display in Base class");
	}

}

class Derived extends Base {

	public void display() {
		System.out.println("Display in Derived class");
	}

}

public class Codekru {

	public static void main(String[] args) {

		Base b = new Base();
		b.display(); /* will call the display method of the "Base" class */

		Derived d = new Derived();
		d.display(); /* will call the overridden method in the derived class */

	}
}

Output –

Display in Base class
Display in Derived class
Code Example 2

Now, what if we use the reference variable of the superclass type, which refers to the object of the subclass type? Then which method will be called ( the one present in the base class or the one present in the Derived class? ).

class Base {

	public void display() {
		System.out.println("Display in Base class");
	}

}

class Derived extends Base {

	public void display() {
		System.out.println("Display in Derived class");
	}

}

public class Codekru {

	public static void main(String[] args) {

		// Here "b" is a reference variable
		// of "Base" class type
		// which is referring to the object of
		// the Derived class type
		Base b = new Derived();
		b.display();

	}
}

Output –

Display in Derived class

So, the method present in the Derived class is called but why?

The method invocations allowed by the compiler are based solely on the declared type of the reference variables and not on the object’s type. But at runtime, the Java Virtual Machine ( JVM ) knows the object’s type to which the variable refers. So, JVM invokes the Derived’s version if the Base class reference variable calls a method overridden by the Derived class.

And that is one of the reasons that method overriding works for the instance methods only and not for the instance variables or the static methods.

Some important points about the Method overriding
  • The argument list must match exactly that of the overridden method. Otherwise, you might end up with overloaded methods instead.
  • The overridden method’s access level in the Derived class cannot be more restrictive than the base class.
class Base {

	public void display() {
		System.out.println("Display in Base class");
	}

}

class Derived extends Base {

	// this is wrong
	// as the access level of this method is private
	// which is more restritive
	// than that of overridden's method
	private void display() {
		System.out.println("Display in Derived class");
	}

}

public class Codekru {

}
  • But the access level can be less restrictive than the overridden method
class Base {

	private void display() {
		System.out.println("Display in Base class");
	}

}

class Derived extends Base {

	// this is correct
	// as the method's access level is public
	// which is less restritive
	// than that of overridden's method
	public void display() {
		System.out.println("Display in Derived class");
	}

}

public class Codekru {

}
  • We cannot override a method marked as final; if we try to do so, we will get a compilation error.
class Base {

	public final void display() {
		System.out.println("Display in Base class");
	}

}

class Derived extends Base {

	// Won't be able to override this method
	// as in superclass, display() is marked final
	public void display() {
		System.out.println("Display in Derived class");
	}

}

public class Codekru {

	public static void main(String[] args) {
		Derived d = new Derived();
		d.display();
	}

}
Exception in thread "main" java.lang.VerifyError: class Test.Derived overrides final method Test.Base.display()V
	at java.base/java.lang.ClassLoader.defineClass1(Native Method)
	at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1016)
	at java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:151)
	at java.base/jdk.internal.loader.BuiltinClassLoader.defineClass(BuiltinClassLoader.java:825)
	at java.base/jdk.internal.loader.BuiltinClassLoader.findClassOnClassPathOrNull(BuiltinClassLoader.java:723)
	at java.base/jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(BuiltinClassLoader.java:646)
	at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:604)
	at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:168)
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522)
  • We cannot override a method marked as static; if we try to do so, we will get a compilation error, as illustrated in the below program.
class Base {

	public static void display() {
		System.out.println("Display in Base class");
	}

}

class Derived extends Base {

	// Won't be able to override this method
	// as in superclass, display() is marked static
	public void display() {
		System.out.println("Display in Derived class");
	}

}

public class Codekru {

	public static void main(String[] args) {
		Derived d = new Derived();
		d.display();
	}

}
Exception in thread "main" java.lang.Error: Unresolved compilation problem: 
	This instance method cannot override the static method from Base

We hope that you have liked the article. If you have any doubts or concerns, please feel free to write us in the comments or mail us at admin@codekru.com.

Related Articles –
Liked the article? Share this on

Leave a Comment

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