Re: generics
On 06/13/2011 05:05 PM, Neil Morris wrote:
Cage<Animal> animalCage=new Cage<animal>
Cage<Lion> lionCage=new Cage<lion>
Cage<cat> catCage=new Cage<cat>
with the above definitions Cage is a subclass of Collection, but with
generics as i understand it the various cages ie Cage<animal> Cage<lion>
and Cage<cat> are not interchangable as below
lionCage.add(catCage)// not allowed!!! even though lionCage and castCage
are subclasses of Collection
could this be because that the various Cages take differant parameters?
To give a fuller explanation:
The purpose of generics (at least, so far as you are using them) is to
declare what is being held by a container. So, in English terms, a
"Cage<Animal>" is a cage that may hold an animal. Logically speaking,
any time you put something into that cage or take it out, it must be
something that is of type Animal.
A "Cage<Lion>" is a cage that may hold a lion, any lion. But even though
a lion is an animal, a Cage<Lion> is not a Cage<Animal>: I can put, say,
a Penguin in a Cage<Animal>, but I can't put a Penguin in a Cage<Lion>;
clearly, the two types must be distinct. Thus generified types do not
follow the type hierarchy with respect to generic type parameters.
As a final note, if you really do want a case where you want to store a
Cage<Lion> into something that is "like" a Cage<Animal>, you can use
wildcards like so: Cage<? extends Animal>, or, in plain English, a cage
that holds things that are animals. The rules of Java work out (this is
a bit of an oversimplification) so that you can't put anything into a
Cage<? extends Animal>, but you know that everything you take out of one
must be some sort of Animal.
--
Beware of bugs in the above code; I have only proved it correct, not
tried it. -- Donald E. Knuth