Open ShyamalSankar opened 3 years ago
If I'm not wrong, the point of using ? super
and ? extends
is to force the covariance nature of how superclasses and classes should work (as Generics are invariant).
You need ? extends R
in the map method as you should be able to map an element to one of its sub-classes, but not the other way round.
Taking the example in the lecture, say you have 3 classes.
FastFood
, Burger extends FastFood
, Cheeseburger extends Burger
As you can see, Cheeseburger <:
Burger <:
FastFood
Say you want to use the map method to perform a transformation from a list of Burgers to something else and assign it to a list of Burgers. You should be allowed to assign a Cheeseburger into the Burger list, and not a FastFood into a Burger list, as a sub-class should have the functions of it's parent and not vice versa.
Therefore, you should be allowed to write a function Function<Burger, Cheeseburger> lambda = x -> new Cheeseburger(x.burger())
//lets say x.burger returns its ID
Therefore, this assignment below should be allowed as it makes sense.
List<Burger> list = burgers.map(lambda)
As all the method you can use in a Burger can also be used in a Cheeseburger
If you write Function<? super T, R>, for this scenario your return type can only be a Burger and you can only write Burger to Burger functions.
? extends R allows the function to return any subclass of R, thus making the function more 'general'. This is similar for ? super T, allowing the function to take in anything that's the super class of T, thus being a bit more flexible in its use.
Hello in lectures we were taught to write map functions like this: (some return type) map(Function<? super T, ? extends R>)
I understand why we need the ? super T in order to take in any functions that work with a super class of T. But what is the point of the ? extends R? Why can't we just write Function<? super T, R> since the type of would be determined based on the function that is passed in?
Thank you!