简体   繁体   中英

Java generic parameters and inheritance

supposed we know that ViewGroup extends View.
Further we have a generic, parametrized class A<T extends View>

Question:
Why wont method C.add() accept new A<ViewGroup>() as parameter?
Shouldn't it work, because of polymorphism?

类图

SOLUTION: Singning add with ? extends View ? extends View lets add accept new A<ViewGroup>() as a parameter.

解

You signed your add method as:

static void add(A<View>)

but you probably meant:

static void add(A<? extends View> a)

Not quite because add() might be using a method of View that is not found in ViewGroup .

Summary: View is a ViewGroup , however ViewGroup is not a View . Polymorphism is where you can assign a View object to a ViewGroup declaration.

First of all, your question isn't very clear because the UML diagram contradicts your text. You say that View extends ViewGroup, but the diagram shows the reverse : ViewGroup extends View.

Now, a List<Car> doesn't extend a List<Vehicle> . If it were the case, you could do:

List<Car> listOfCars = new ArrayList<Car>();
List<Vehicle> listOfVehicles = listOfCars;
listOfVehicles.add(new Bicycle());
// now the list of cars contain a bicycle. Not pretty. 

First of all you said View extends ViewGroup, but the diagram says ViewGroup extends View (which I assume to be right).

Secondly, you are not allowed to pass a List<ViewGroup> as a List<View> . This is a compile time protection to prevent someone from adding an AnotherView into this list and compromise type-safety of generics.

List<ViewGroup> is not a subtype of List<View> , but it is a subtype of List<? extends View> List<? extends View> . So you can modify your method to accept a List<? extends View> List<? extends View> instead, but be aware that you can't add to the list passed to the method this way.

There is also another syntax called lower bound wildcard ( List<? super ViewGroup> ), as opposed to the upper bound wildcard mentioned above, which enables you to add to the list but you can olny pass in a list of ViewGroup or its parents.

More about wildcards in generics can be found here: http://download.oracle.com/javase/tutorial/java/generics/wildcards.html

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