Harish-
It doesn't like the "q=t;" line because there is no guarantee that t is of a type that can be legitimately assigned to q. The extends clause makes guarantees about all Q2 objects being instances of Test objects, but none about Test objects being instances of Q2 objects.
For instance, let's say we had the following 3 classes:
Fruit Pear extends Fruit
Apple extends Fruit
Example #1
These are ok because p1 and a1 are guaranteed to be fruit since both Pear and Apple extend Fruit.
Pear p1 = new Pear();
Apple a1 = new Apple();
Fruit f1;
f1 = p1;
f1 = a1;
Example #2
This is not ok:
Pear p2;
Fruit f2 = new Pear();
p2 = f2; // f2 might be a Pear, but might not.
In this case it was, but we could just as easily have change the previous line to be Fruit f2 = new Apple(); or Fruit f2 = getRandomFruit(); and then we would be assigning an Apple (or who knows what) to a Pear.
Example #3
This is ok, because of the explicit casting:
Pear p3;
Fruit f3 = new Pear();
p3 = (Pear)f3; // casted
Hope that helps.
Josh