简体   繁体   中英

Java subclass as parameter

Class A
Class B extends A

public static List<A> doSomething(List<A> items, A item) {
    // manipulate items
    return items;
}

List<B> items = new ArrayList<B>();
B item = new B();

items = doSomething(items, item);

ERROR: The method doSomething(List< A>, A) is not applicable for the arguments (List< B>, B)

item is accepted, but items in not. Why Can't I do that?

And how is the correct way?

You have to use List<? extends A> List<? extends A> .

List<B> does not extend List<A> . There are good reasons for that; informally, consider that the contract for List<A> " you can put an instance of A in it " is not valid for List<B> .

You need to indicate that you are willing to accept lists with subtypes of A . You can do that with a wildcard like List<? extends A> List<? extends A> . However then your return type also becomes List<? extends A> List<? extends A> and you don't want that. What you really want is that if you pass in List<B> , the return type is List<B> .

To do this properly without casts, you need to bind the type and specify it can sublass A.

public static <T extends A> List<T> doSomething(List<T> items, T item) {
    // manipulate items
    return items;
}

This should work.

Even if B is subclass of A, List is not a subclass of List.

You should change your method in this way:

public  static  List<? extends A>doSomething(List<? extends A> items, A item) {
    // manipulate items
    return items;
}

and call it by casting the return value:

items = (List<B>) doSomething(items, item);

Be aware that in this way you can call the method passing as a parameter also a List of other potentially subclasses of A, and then the return value will be a List of that subclass (ie not a List), so it is your responsibility to know if the cast is legal or not.

I think both items and item are not accepted. if you replace like wise

List<A> items = new ArrayList<A>();
B item = new B();

items = doSomething(items, item);

Now you will get the

ERROR: The method doSomething(List< A>, A) is not applicable for the arguments (List< A>, B)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM