Learn Java

Covariant Return Types in Java

As you already know, in Java, method overriding is a mechanism for providing new behavior for the superclass method in a subclass method.

Note that the terms subclass and child class in Java are used interchangeably, as are superclass and parent class. A subclass (or child class) inherits from a superclass (or parent class), allowing it to reuse or override the behaviors defined in the superclass.

Method overriding follows a set of specific rules. When you override a superclass method, the name and parameters of a subclass method have to be exactly the same as that of the superclass method. The situation with regards to the return type, however, is slightly different. The subclass method can return the same type as the superclass method or a subtype of that return type. This feature is known as the covariant return type.

How it works

Covariant return type allows you to narrow (but not widen) the return type of the overridden method, that is, to make it more specific.

The following picture demonstrates the covariance with respect to the type B. If the superclass method returns B then an overriding subclass method can return B, D or E, but not A, C or F.

Covariance with respect to the type B

Covariance with respect to the type B

Let's consider the following code:

class SuperType { }

class SubType extends SuperType { }

class A {
    
    public SuperType getType() {
        return new SuperType();
    }
}

class B extends A {
    
    @Override
    public SubType getType() {
        return new SubType();
    }
}

In this example, the SubType class inherits from SuperType. The method getType of A returns an instance of SuperType, but the overridden method getType of the class B (that extends A) returns an instance of SubType. There are no compile-time errors, this overriding method works perfect.

In the example shown below, we get a compiler error:

class A {
    
    public SubType getType() {
        return new SubType();
    }
}

class B extends A {
    
    @Override
    public SuperType getType() {
        return new SuperType();
    }
}

Here, the method getType of the class A returns an instance of SubType, while the overridden method getType of the class B returns an instance of SuperType. It's not a covariant return type so this code does not compile.

Summary

Remember, when overriding a subclass method, the return type can be the same type or a subclass of the return type of a superclass method. Covariance is always changing down the hierarchy.

It is also important to note that the co-variant return types are possible only for non-primitive return types.

Written by

Master Java by choosing your ideal learning course

View all courses

Create a free account to access the full topic

Sign up with Google
Sign up with Google
Sign up with JetBrains
Sign up with JetBrains
Sign up with Github
Sign up with GitHub
Coding thrill starts at Hyperskill
I've been using Hyperskill for five days now, and I absolutely love it compared to other platforms. The hands-on approach, where you learn by doing and solving problems, really accelerates the learning process.
Aryan Patil
Reviewed us on