Lion
Lion

Reputation: 19037

Covariant return type in 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.

Upvotes: 9

Views: 17850

Answers (4)

neoexpert
neoexpert

Reputation: 468

I checked the byte code with javap command for the OPs example and found out, that the Compiler generates an additional method in the SubClass class:

//1
public java.util.List getList();

which invokes the

//2
public java.util.ArrayList getList();

method and returns it's result.

SubClass sc=new SubClass();
//the ArrayList getList() will be invoked:
sc.getList();

SuperClass s=...;
//the List getList() will be invoked:
s.getList();

Upvotes: 0

emory
emory

Reputation: 10891

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.

Upvotes: 20

AZ_
AZ_

Reputation: 21899

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

Upvotes: 5

lrAndroid
lrAndroid

Reputation: 2854

Yes, that is correct. Since an ArrayList is a List, you can return an ArrayList when the original method returned a List.

Upvotes: 3

Related Questions