-1

This is my problem. I would like to write a function that accepts List containing a given class AND its subclasses.

For example:

class B extends  A
class C extends  A

I need a function with a List parameter that accepts A, B and C.

It only accepts B and C

public void f(List<? extends A> list)

It only accepts A

public void f(List<A> list)

How can it accepts A, B and C?

Alexis C.
  • 91,686
  • 21
  • 171
  • 177
user2693979
  • 2,482
  • 4
  • 24
  • 23

4 Answers4

1

This is to do with generic rules:

in general if B extends A and you have a generic type G, then

    g<a> 

cannot be initialised to

    g<B>.

This is because the following would then be possible: class Human and Dog extend class Animal

    public void makeNoise(List<? extends Animal> animalList) {
        for (Animal a: animalList) {
    //now you could call a.bark() or a.speakAsHuman() and there could not be any verification of whether this is a list of dogs or humans
    }

}

Have a look at: this SO Question

Community
  • 1
  • 1
Saad Attieh
  • 1,396
  • 3
  • 21
  • 42
1

List<? extends A> accepts List<A> and List<B> and List<C>, there's no problem with it.

Sotirios Delimanolis
  • 274,122
  • 60
  • 696
  • 724
Erik Ghonyan
  • 427
  • 4
  • 12
1

This cant be done because of the concept of Erasure. At runtime both of your 'f()' methods look identical to the compiler and so it will complain you have the same method twice. You have to remember that type parameters are erased at runtime so you have a method that looks like:

public void f(List list);

Therefore you cant invoke f polymorphicaly even this is illegal:

public void f(List<String> list);
public void f(List<Integer> list);

If you have separate method names you can do the following:

public void f(List<? extends A> list);
public void g(List<A> list);
public void h(List<? super B> list);

In method F you could pass any A or subtype of A. G will require a list of A objects only and h will take a list of b or any supertype of B. There is no way to specify sibling classes.

Some references of interest: http://docs.oracle.com/javase/tutorial/java/generics/lowerBounded.html http://docs.oracle.com/javase/tutorial/java/generics/upperBounded.html

Robert Simmons Jr.
  • 1,182
  • 8
  • 21
  • Oracle Guidelines for Wildcard use can be found at http://docs.oracle.com/javase/tutorial/java/generics/wildcardGuidelines.html – Daniel Jan 07 '14 at 22:00
-2

You can't write one single prototype to accept both because List<B> is not a subclass of List<A>. See: Is List<Dog> a subclass of List<Animal>? Why aren't Java's generics implicitly polymorphic? However you can write two prototypes to accept each:

class c {
    public void f(List<? extends A> list);
    public void f(List<A> list);
}
Community
  • 1
  • 1
lindenrovio
  • 357
  • 3
  • 13