Table of contents
1.
Introduction
2.
What is a Covariant Return Type in Java?
2.1.
Example 1
2.1.1.
Code:
2.2.
Java
2.2.1.
 
2.2.2.
Output
2.2.3.
Explanation
2.3.
Example 2
2.3.1.
Code
2.4.
Java
2.4.1.
Output
2.4.2.
Explanation
3.
Advantages of Covariant Return Type in Java
4.
Disadvantages of Covariant Return Type in Java
5.
How are Covariant return types implemented?
6.
Frequently Asked Questions
6.1.
What is covariance of return type?
6.2.
What is covariant vs contravariant return type?
6.3.
How is covariant return type implemented in Java?
7.
Conclusion
Last Updated: Jul 3, 2024
Medium

Covariant Return Type in Java

Author Lokesh Sharma
1 upvote

Introduction

The covariant return type In Java allows a subclass method to return a more specific type than the return type of the overridden method in the superclass. This means that if a method is overridden in a subclass, then the return type of the overriding method can be a subtype of the return type of the overridden method.

In this article, we will learn about covariant return type in Java. This topic is important if you wish to master method overloading. We will understand the need for using the covariant return type in Java by considering some simple examples. 

Covariant Return Type in Java

Must Read, Multithreading in java, Fibonacci Series in Java

What is a Covariant Return Type in Java?

Covariant return type refers to the return type of an overriding method. This statement means that the return type of the sub-class method can be a covariant(may vary in the same direction) of the parent method’s return type.

Covariance means that the two return types should be of similar type and not vary so much in properties. For example, String is a covariant of the object data type. The feature of covariant return type in java was introduced in Java 5. Before java 5, we could not do method overriding by changing the return type. The overriding method must be invariant for the return type.

However, Java 5 introduced this new return type feature while overriding. Now a derived class function need not have the same return type as the overridden function of the parent class. 

Note1: We use covariant return types only in the case of non-primitive return types. Secondly, the child method’s return type must be a subtype of the parent method’s return type. 

Note2: When dealing with covariant return types, make sure that the methods present in the child class must not override the parent class’s methods and vice versa. 

Let us take some simple examples of covariant return type in java.

Example 1

File Name: BMW.java

Code:

  • Java

Java

// parent class
class Car{   
   Car get(){
       System.out.println("This is the Car class.");
       return this;
   }   
}   
 
// child class
class BMW extends Car{  
@Override 

// overloading the get method
   BMW get(){
       System.out.println("This is the BMW class.");
       return this;
   }
   
   public static void main(String args[]){   
       Car MyCar = new BMW();
       MyCar.get();  
   }   
}   
You can also try this code with Online Java Compiler
Run Code

 

Output

This is the BMW class.
You can also try this code with Online Java Compiler
Run Code

Try it on online java compiler.

Explanation

Look at the code carefully. We create a Car class with a get() method. We then derive a BMW class from the Car class. In the BMW class, we override the get() method. But see, instead of having the return type as Car, we return an object of type BMW. This code works perfectly fine even though the return type of children and parent did not match. However, BMW as a return type works alright because it is a subclass of the Car class. 

Example 2

Code

  • Java

Java

class A {
}

// An object of class B will be
// a subtype of an object of class A
class B extends A {
}

class Parent {

   A fun()
   {
       // This function just displays a message
       System.out.println("Hi, this message is sent by the parent class.");
       return new A();
   }
}

class Child extends Parent{
   @Override
  
   // overloading the fun function
   B fun()
   {
       System.out.println("Hello, this message is sent by the child class.");
       return new B();
   }
}


// the main function
public class CodingNinjas {

   // Main driver method
   public static void main(String args[])
   {

       // creating object of the parent class
       Parent base = new Parent();

       // Calling method fun() over this object
       base.fun();

       // Creating object of child class
       Child derived = new Child();

       // Again calling method fun() over this object
       derived.fun();
   }
}
You can also try this code with Online Java Compiler
Run Code

 

Output

Hi, this message is sent by the parent class.
Hello, this message is sent by the child class.
You can also try this code with Online Java Compiler
Run Code

Explanation

The interesting thing to note about this example is that we created our own covariant data types. An object of class B is covariant to the object of class A. The reason being B is a subclass of A. So when overloading the fun() function in the child class, we have created an object of B class. As you can see, the code runs perfectly and gives the desired output.

Also see, Duck Number in Java and Hashcode Method in Java

Advantages of Covariant Return Type in Java

Let us look at the benefits that the covariant return type in java provides us. The following points will help us realize the need for this return type.

  1. The covariant return type in Java helps us to write readable, usable, and maintainable code. Cleanliness of code becomes very essential when developing large applications.
     
  2. We can avoid using confusing typecasts and be more specific while returning the data type. 
     
  3. Careful implementation of the covariant return type in java reduces the run-time ClassCastExceptions. 

Disadvantages of Covariant Return Type in Java

  • Potential Confusion: Covariant return types can lead to confusion and make code harder to understand, especially in complex inheritance hierarchies.
     
  • Compatibility Issues: They can create compatibility issues when subclass methods return a more specific subtype than the superclass method, affecting method overriding.
     
  • API Design Considerations: Overuse of covariant return types can complicate API design and make it harder to maintain and extend code over time.
     
  • Potential for Runtime Errors: Incorrect implementation or misuse of covariant return types can lead to unexpected runtime errors or type mismatches.
     
  • Not Widely Used: Covariant return types are not widely used in practice due to the complexity they introduce and the potential for subtle bugs.

How are Covariant return types implemented?

Covariant return types are implemented in Java by allowing a subclass method to override a superclass method and return a subtype of the superclass method's return type. This means that the return type of the overriding method must be a subtype of the return type of the overridden method.

In order to implement a covariant return type, the subclass method must have the same method signature as the superclass method, including the name, parameter types, and order. However, the return type of the subclass method can be a subtype of the return type of the superclass method.

class Animal {
   public Animal giveBirth() {
       // Animal gives birth to another animal
       return new Animal();
   }
}
class Cat extends Animal {
   @Override
   public Cat giveBirth() {
       // A cat gives birth to another cat
       return new Cat();
   }
}

In this example, the Cat class overrides the giveBirth() method of the Animal class and returns a Cat object instead of an Animal object. This is allowed because Cat is a subclass of Animal, and a Cat object can be used in place of an Animal object.

Note that covariant return types are only allowed for non-private instance methods in Java. Static methods, constructors, and private methods cannot have covariant return types. Additionally, the subtype returned by the overriding method must be a valid subtype of the return type declared in the overridden method.

Check out this article - Upcasting and Downcasting in Java

Frequently Asked Questions

What is covariance of return type?

Covariance of return type allows a subclass method to return a more specific type than its overridden method in the superclass. The return type of the overriding method can be a subtype of the return type of the overridden method.

What is covariant vs contravariant return type?

In Java, a covariant return type allows a subclass method to return a more specific type than its superclass method. Contrarily, a contravariant return type would allow a subclass method to return a less specific type than its superclass method.

How is covariant return type implemented in Java?

In Java, covariant return type is implemented by allowing a subclass method to return a subtype of the superclass method's return type. The subclass method must have the same signature as the superclass method but can return a more specific type.

Conclusion

In this article, we discussed the covariant return type in java. We understood it's working with an example. The covariant return type in Java helps us to write readable, usable, and maintainable code. Cleanliness of code becomes very essential when developing large apps.

We hope you enjoyed reading this article. If you wish to learn more about return types and data types in java, refer to data types and return types.

You can also refer to these interesting article by coding ninjas. We also suggest you check out our course on Java.

Visit our website to read more such blogs. Make sure you enroll in our other courses as well. You can take mock testssolve problems, and interview puzzles. Also, you can check out some exciting interview stuff- interview experiences and an interview bundle for placement preparations. Do upvote our blog to help fellow ninjas grow.

Live masterclass