Covariant Return Types In Java

As we already know what method overriding is, the subclass providing new implementation of the super class method provided that the method signature in subclass should exactly match with method signature of super class including the return types.

The covariant return types are newly introduced since Java 5.0, and used during method overriding. Covariant return type allows us to change the return type of the overriding method in the subclass; however this return type in subclass method must be a subtype of super class method return type.

Also Check: Java Interview Questions and Answer

Simply put, overriding method (in subclass) can have a return type that is subtype of overridden method return type (in superclass). If this concept is confusing, it can be explained best with an example:


class Vehicle {
public Vehicle move(String direction) {
return new Vehicle();
}
}
class Van extends Vehicle {
public Vehicle move(String direction) {
return new Vehicle();
}
}

In the above code example, we have two classes Vehicle and Van. The Van class is a subclass of Vehicle by inheritance. Also, we are overriding the method move() in the subclass with exactly same parameters and return type. The Van class is subclass of Vehicle. In other words, Van is a subtype of Vehicle (or Van is a Vehicle). Now, in order to make use of covariant return types, let us change the subclass’s overriding method return type to Van.


class Van extends Vehicle {
// Notice the covariant return type Van here, which is subtype of Vehicle
public Van move(String direction) {
return new Van();
}
}

The above code compiles with Java 5.0 because covariant return types are only introduced from Java 5.0. If we try to compile above code with Java 1.4 compiler, we get compiler error.

javac -source 1.4 Van.java
attempting to use incompatible return type

Since we understood the concept of covariant return types, the following is a full example which demonstrates covariant return type.

class Vehicle {
public Vehicle getInstance() {
return this;
}
}
class Van extends Vehicle {
// Covariant return type in action!!!
public Van getInstance() {
return this;
}
public void move() {
System.out.println("Van is moving ...");
}
}
public class CovariantTest {
public static void main(String... args) {
new Van().getInstance().move();;
}
}

Output
Van is moving.

The previous code example is improved by adding getInstance() method to Vehicle class and overriding this method in subclass Van. The implementation of this getInstance() method returns ‘this’, which is returns Vehicle instance in the Vehicle class method and Van instance in the overridden Van class method respectively. Notice how the getInstance() method is overridden with covariant return type (Van in this case).

So, the advantage of covariant return types is that, we can have more specific return types when overriding methods. This avoids unnecessary confusing type casts in the class hierarchy thus making the code more readable and maintainable.

About Aditi Malhotra

Aditi Malhotra is the Content Marketing Manager at Whizlabs. Having a Master in Journalism and Mass Communication, she helps businesses stop playing around with Content Marketing and start seeing tangible ROI. A writer by day and a reader by night, she is a fine blend of both reality and fantasy. Apart from her professional commitments, she is also endearing to publish a book authored by her very soon.

Leave a Comment

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

Scroll to Top