I'm moving over to java from DotNet and this idea of extends is new.
I've seen some posts that fully explain using List<? extends SomeAbstract>
vs. List<? super SomeAbstract>
vs. List<SomeAbstract>
, but I'm guessing that there is no difference between using, and not using, extends in generics.
Is that true? Would the answer change if using an abstract class as the parent?
class My_AbstractExtends<T extends SomeAbstract>
vs.
class My_Abstract<SomeAbstract>
Creates child classes as follows
class My_ChildExtends extends My_AbstractExtends<ConcreteChildOfSomeAbstract>
vs.
class My_Child extends My_Abstract<ConcreteChildOfSomeAbstract>
I'm guessing you're talking about the use of extends in type parameter declarations. In that case:
class My_Abstract<T extends SomeAbstract>
has a bounded type parameter called T
that must be SomeAbstract
or some subtype of it.
class My_Abstract<SomeAbstract>
has an unbounded type parameter called SomeAbstract
that could be anything. Note that SomeAbstract
no longer refers to the actual type SomeAbstract
that the first example uses at all!
To expand on that: imagine if the second declaration were class My_Abstract<T>
. The T
there is clearly a type parameter, not an actual type. But it doesn't have to be called T
... it can be called E
or Bob
or SomeAbstract
. In all of these cases, it is still just a type parameter... an actual type can never go there, nor does it make any sense for it to (the whole point of a type parameter is to NOT refer to a specific type but instead allow other types to be put in its place when instances of the class are created).
In the code you've edited in, change My_Child
's declaration to
class My_Child extends My_Abstract<Object>
and you'll see the difference. If you actually try to do something using the type parameter SomeAbstract
in the second version, you'd also find that you cannot call any methods declared in the real SomeAbstract
class. This is all a good example of why you should always follow the convention of using single-letter type parameters... it's really confusing if you don't.
This is getting really long, but I also want to note that all of this is basically unrelated to the first half of your question. Wildcards like ? extends SomeAbstract
and ? super SomeAbstract
aren't used in type parameter declarations (such as those used when defining a generic class), they're primarily used for method parameters. List
is a typical example for explaining why wildcards are needed because its nature as a container of objects makes it relatively easy to understand, but rules pertaining to them apply to any generic type. I tried to explain this in relatively general terms in this answer.
It lets you refer to T
in other places.
public class A<T extends SomeClass>{
public A(T x){this.x=x;}
public T x;
}
Then users of your class can use their original type instead of having to use SomeClass.
MyObject x = new A<MyObject>(new MyObject()).x;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With