Cannot pass ArrayList<Impl> to method taking ArrayList<Interface>

I have an interface and a class implementing it:

public interface IFoo{
    Integer bar();
}

public class Foo implements IFoo{
    @Override
    public Integer bar(){
        return 42;
    }
}

Now in another class, I have a function which takes an ArrayList of the interface type.

public class Something {
    public static void function(ArrayList<IFoo> foos){
        //do something on foos
    }
}

I want to use this function on an array list of Foo:

ArrayList<Foo> myFoos = new ArrayList<Foo>();
Something.function(myFoos);//can NOT do this

What is the problem or what shall I do?

Upvotes: 1

Views: 105

Answers (3)

user2864740
user2864740

Reputation: 61885

I would probably leave the method signature unchanged (except to accept an List<IFoo>) and promote the usage of the interface type, such as:

List<IFoo> myFoos = new ArrayList<IFoo>();

If needing to use List<Foo> - again, away with the ArrayList! - then I would likely still keep the simpler signature and force the caller to cast as appropriate, or otherwise provide a List<IFoo> expression, leaving the responsibility of such an operation at the call-site.

(I'm largely biased against subtyping, and prefer to sidestep this covariance issue entirely when practical.)

Upvotes: 1

John Kugelman
John Kugelman

Reputation: 361625

Generics to the rescue!

public static void function(ArrayList<? extends IFoo> foos){
    //do something on foos
}

Now the function takes any kind of array list where the contained type is either IFoo or is derived from it.

For what it's worth, it's also a good idea to use the most generic type possible. Do you really need an ArrayList, or would any kind of List do? Or maybe any kind of Collection?

public static void function(List<? extends IFoo> foos);
public static void function(Collection<? extends IFoo> foos);

A good rule of thumb is to be conservative in what you send and liberal in what you accept from others. Using more generic parameter types falls under the "be liberal" part.

Upvotes: 6

user3145373 ツ
user3145373 ツ

Reputation: 8146

you can do it by using generics :

public static void function(ArrayList<? extends IFoo> foos){

}

So your problem is easily get solved.

Upvotes: 0

Related Questions