1

here is the scenario

class MyClass1{

}

class MyClass2 extends MyClass1{

}

class Parent<T>{
 List<T> list;
}


class Child extends Parent<MyClass2>{
}

this doesn't compile

Parent<MyClass1> p = new Child();

this does

Parent<MyClass2> p = new Child();

why?

is there a way to refer via parent type?

Saqib
  • 1,737
  • 2
  • 19
  • 30
  • 1
    possible duplicate of [Is List a subclass of List? Why aren't Java's generics implicitly polymorphic?](http://stackoverflow.com/questions/2745265/is-listdog-a-subclass-of-listanimal-why-arent-javas-generics-implicitly-p) – Daniel Pryden Mar 05 '15 at 00:33

4 Answers4

3

This is how generics works. You've explicitly stated that class Child is a subclass of Parent<MyClass2>. But Parent<MyClass2> is not a subclass of Parent<MyClass1>, so therefore Child is not a subclass of Parent<MyClass1>.

Change your constructor call to

Parent<? extends MyClass1> p = new Child();
TNT
  • 2,900
  • 3
  • 23
  • 34
3

This line

Parent<MyClass1> p = new Child();

doesn't compile, because the Child class has defined the type parameter T to be MyClass2. All Child objects are Parent<MyClass2> objects, and a Parent<MyClass2> is not a Parent<MyClass1>, even if a MyClass2 is a MyClass1. That's because Java's generics are invariant.

The solution to get this to compile when using MyClass1 is to use a bounded wildcard.

Parent<? extends MyClass1> p = new Child();

The wildcard allows the relationship between MyClass2 and MyClass1 to extend to Parent<MyClass2> and Parent<? extends MyClass1>.

rgettman
  • 176,041
  • 30
  • 275
  • 357
1

What you are talking about is a concept called covariance. In your implementation the fact that MyClass1 extends MyClass2 does not mean that Parent<MyClass1> extends Parent<MyClass2> so Parent<MyClass1> p = new Child(); does not compile.

You have to explicitly mention this in your instantiation:

Parent<? extends MyClass1> p = new Child();

So now you tell compiler that T is subclass of MyClass1 so compiler let it go.

Nami
  • 1,215
  • 11
  • 21
0

With your Child class definition, you're stating that the only type of Generic Parent will accept is MyClass2. If you want both MyClass1 and MyClass2 to be accepted as Generics in Parent, do this:

class MyClass1{}
class MyClass2 extends MyClass1{}
class Parent<T extends MyClass1>
{ List<T> list; }
class Child<T extends MyClass1> extends Parent<T>{}
jdb1015
  • 127
  • 6