Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Covariant return type in Java

Tags:

java

The following code uses the concept of method overriding in Java.

package pkg;

import java.util.ArrayList;
import java.util.List;

abstract class SuperClass
{
    abstract public List<String>getList();
}

final class SubClass extends SuperClass
{
    private List<String>list=null;

    @Override
    public ArrayList<String> getList()
    {
        list=new ArrayList<String>();
        list.add("A");
        list.add("B");
        return (ArrayList<String>) list;
    }
}

final public class Main
{
    public static void main(String[] args)
    {
        SuperClass s=new SubClass();
        List<String>list=s.getList();

        for(String str:list)
        {
            System.out.println(str);
        }
    }
}

By convention, method overriding uses the same signature (with return type) in both super class and subclass. In the above code, the return type of the getList() method in the SuperClass is List and in its subclass the return type is ArrayList. How does method overriding work here?

By the way, it's obvious that ArrayList is an implementation of the List interface but how does the compiler treat the return type here while overriding the getList() method?

Should I believe something like this... The return type of the overridden method is allowed to be a subtype of the overridden method's return type.

like image 505
Lion Avatar asked Apr 13 '12 02:04

Lion


2 Answers

Yes.

In early java that was not the case, but it was changed in Java 5.0.

You cannot have two methods in the same class with signatures that only differ by return type. Until the J2SE 5.0 release, it was also true that a class could not override the return type of the methods it inherits from a superclass. In this tip you will learn about a new feature in J2SE 5.0 that allows covariant return types. What this means is that a method in a subclass may return an object whose type is a subclass of the type returned by the method with the same signature in the superclass. This feature removes the need for excessive type checking and casting.

The source of this information is no longer available on the interwebs.

like image 198
emory Avatar answered Oct 24 '22 06:10

emory


In object-oriented programming, a covariant return type of a method is one that can be replaced by a "narrower" type when the method is overridden in a subclass. A notable language in which this is a fairly common paradigm is C++. Covariant return types have been (partially) allowed in the Java language since the release of JDK5.0, so the following example wouldn't compile on a previous release:

 // Classes used as return types:

 class A {
 }

 class B extends A {
 }

 // "Class B is more narrow than class A"
 // Classes demonstrating method overriding:

 class C {
     A getFoo() {
         return new A();
     }
 }

 class D extends C {
     B getFoo() {
         return new B();
     }
 }

More specifically, covariant (wide to narrower) or contravariant (narrow to wider) return type refers to a situation where the return type of the overriding method is changed to a type related to (but different from) the return type of the original overridden method.

The relationship between the two covariant return types is usually one which allows substitution of the one type with the other, following the Liskov substitution principle.

This usually implies that the return types of the overriding methods will be subtypes of the return type of the overridden method. The above example specifically illustrates such a case. If substitution is not allowed, the return type is invariant and causes an compile error.

Reference: https://en.wikipedia.org/wiki/Covariant_return_type

like image 27
AZ_ Avatar answered Oct 24 '22 05:10

AZ_