This tutorial explains about covariant return type in java and how we can override a method using covariant return type. The tutorial explains different aspect of covariant return type along with the advantages of using this.
What is Covariant return type in Java
If type(class) B can be used as a return type while overriding a method whose return type is A, then we call type B as a covariant type of type A. In java this is possible only when type B is a subclass of type A. So we can say all subtypes of a type are covariant type of that type. Covariant return type is applicable for non primitive types only.
Method overriding using covariant return type in Java
If a method in a class returns a non primitive type, then the same method in a subclass of that class can use the same non primitive type or a subclasses of that non primitive type as the return type to override that method.
Let's understand this by an example. In java we have a class Integer
which extends a class Number
which implicitly extends Object
class,
so the inheritance structure looks like below.
If a class A has a method whose return type is an Object
type, then the same method in a child class B(child of class A) can use Number
or
Integer
as return type to override that method because Number
and Integer
class are covariant of Object
class.
Let's see this by the program given below :
Can we override a method which returns Object
type with any non primitive type ?
Yes we can, since Object
class is superclass of every class in java.
Java program of method overriding using covariant return type
class
A {Object
print() { System.out.println("print method of class A"
);return new
Object(); } }class
Bextends
A {Integer
print() { System.out.println("print method of class B"
);return new
Integer(2); }public static void
main(String [] args) { B b =new
B(); b.print(); A a =new
B(); a.print(); } }
Output:
print method of class B print method of class B
As you can observe from the output, the print method in class B is overriding the print method of parent class A though the return type of child class method is Integer
type It's
happening because java allows to use covariant return type while overriding the method.
Let's see one more program to understand it more clearly.
class
A { }class
Bextends
A { }class
Cextends
A { }class
D {public
A print() { System.out.println("print method of class D"
);return new
A(); }public
A message() { System.out.println("message method of class D"
);return new
A(); } }class
Eextends
D {public
B print() { System.out.println("print method of class E"
);return new
B(); }public
C message() { System.out.println("message method of class E"
);return new
C(); }public static void
main(String [] args) { E e =new
E(); e.print(); D d =new
E(); d.message(); } }
Output:
print method of class E message method of class E
Here you can see the return type of print and message method of class D is A and we are able to override these methods in class E just by changing the return type as subclasses of class A. It's just because class B and class C are covariant type of class A since both are it's subtypes.
Rules of overriding a method using covariant return type
- The covariant return type is applicable only for non primitive or object types, not for primitive types.
- The return type of overriding method in child class can not be a return type which is parent of superclass method's return type. Doing so will result in compilation error.
- The overriding method's return type in child class should be either the same as the parent class method's return type or a subclass of that type.
Advantages of covariant return type in Java
- It gives you freedom to return more specific return type while overriding the method which may eliminates unnecessary downcasting from the super type to the subtype.
For example clone method of Object class can be overriden by implementing
Clonable
interface and the implementing class can return the object of its own type which will always be better than returningObject
type. - It helps us in preventing runtime ClassCastException.