In Java, covariance allows the API designer to specify that an instance may be generalised as a certain type or any of that type\'s subtypes. For example:
Li
Well, your second example would allow you to write:
Shape shape = getShapeFromSomewhere();
shapes.add(shape);
whereas you couldn't do that with the first form. It's not useful as often as covariance, I'll grant you.
One area where it can be useful is in terms of comparisons. For example, consider:
class AreaComparer implements Comparator
...
You can use that to compare any two shapes... so it would be nice if we could also use it to sort a List for example. Fortunately, we can do that with contravariance, which is why there's an overload for Collections.sort of:
public static void sort(List list, Comparator super T> c)