1

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?

3
  • 2
    Slightly off topic, but why not public static void function(IFoo foos...) ? Commented Sep 29, 2014 at 5:42
  • I agree with @Leon. Coding to the interface is a good practice. Commented Sep 29, 2014 at 5:43
  • your interface name is IFoo and arraylist your are generating is for Foo. however inside Something class in function signature you have mentioned correctly. Commented Sep 29, 2014 at 5:43

3 Answers 3

6

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.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks. Collection type may depend.
1

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.)

4 Comments

Okay, I'll bite. Why are you biased against subtyping?
@JohnKugelman Not so much subtyping as inheritance subtype-relationsips: mainly the increased (and too-easy) dependence upon LSP (beyond a defined interface contract) and concrete types.
Ah, gotcha. I'm in agreement with you there. I thought you had something against wildcard qualifiers specifically. That'd be an oddly specific thing to hate. ;-)
@JohnKugelman Oh no, not at all - but if I can do away without such then I'll try and do so first. (This question isn't a really good example of when they really shine.)
0

you can do it by using generics :

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

}

So your problem is easily get solved.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.