Confusion using a parameterized collection with a sub class

Discussion in 'Java' started by dugrocker, Aug 17, 2006.

  1. dugrocker

    dugrocker Guest

    Hi,

    I've got a super class A and A subclass of A called B. I want to make a
    collection that can be created as either a collection of A or a
    subclass of A. That is fine, and seems to compile fine.

    However, when I actually make a collection that contains a subclass of
    A (B in this example), I cannot add elements of B to the collection.

    Does anyone know the solution?

    Code snippet below:
    <code>

    package generics;
    import java.util.ArrayList;

    public class MyContainer
    {
    ArrayList<? extends A> bList; //The list should be a list of
    something
    //that either extends or
    is an A. B
    //Fullfills this
    requirement


    MyContainer()
    {
    bList = new ArrayList<B>();//List of child class B (compiles)
    }

    public static void main(String[] args)
    {
    MyContainer myContainer = new MyContainer();


    /* *********************************************************
    * The problem is here in the next line.
    *
    * Compiler message:
    *
    * The method add(capture-of ? extends A) in the type
    * ArrayList<capture-of ? extends A> is not applicable for the
    * arguments (B)
    *
    * *********************************************************/
    myContainer.bList.add(new B()); //(fails to compile)

    }
    }

    </code>
     
    dugrocker, Aug 17, 2006
    #1
    1. Advertising

  2. dugrocker

    Oliver Wong Guest

    "dugrocker" <> wrote in message
    news:...

    > ArrayList<? extends A> bList; //The list should be a list of
    > something
    > //that either extends or
    > is an A. B
    > //Fullfills this
    > requirement
    >

    [...]
    >
    > /* *********************************************************
    > * The problem is here in the next line.
    > *
    > * Compiler message:
    > *
    > * The method add(capture-of ? extends A) in the type
    > * ArrayList<capture-of ? extends A> is not applicable for the
    > * arguments (B)
    > *
    > * *********************************************************/
    > myContainer.bList.add(new B()); //(fails to compile)


    First of all, realize that when a class extends another class, there is
    an IS-A relationship formed between the two classes. That is, if B extends
    A, then for any given instance of B, you can say that that instance IS-A A.
    This more intuitive if you use real class names. Let's say Vehicule and Car.
    Car extends Vehicule, and so you can say that a car IS-A Vehicule.

    bList is an ArrayList<? extends Vehicule> which in informal terms means
    it's a list of something which extends vehicule. Let's give that something a
    name: call it S. Now you don't actually know what S is, only that S extends
    Vehicule. So S could be Vehicule itself, or it could be Car, or it could be
    some other class that extends Vehicule (such as Boat).

    You can never add anything to this list. Why? Because there's no way to
    guarantee that whatever it is your adding extends S. In the above example,
    you're trying to add Car to the list, but it's not clear that the list can
    accept Car, because Car might not extend S. (e.g. Car doesn't extend Boat,
    so if S is actually Boat, you couldn't add the Car to a list of boats)

    My guess is that you don't actually want an ArrayList<? extends
    Vehicule>, but rather an ArrayList<Vehicule>. This is saying that you have a
    list of vehicules. You can put a car in a list of vehicules, because a car
    IS-A vehicule.

    - Oliver
     
    Oliver Wong, Aug 17, 2006
    #2
    1. Advertising

  3. dugrocker

    dugrocker Guest

    So, what are you saying, if you make the following statement,
    "ArrayList<? extends A> aList;" you will be able to instantiate it as
    an ArrayList<A> or ArrayList<subclass of A> but you will never be able
    to add any objects to it?

    This syntax, ArrayList<? extends A>, should only be used in a method
    signature then, and not in a variable declaration?

    > First of all, realize that when a class extends another class, there is
    > an IS-A relationship formed between the two classes. That is, if B extends
    > A, then for any given instance of B, you can say that that instance IS-A A.
    > This more intuitive if you use real class names. Let's say Vehicule and Car.
    > Car extends Vehicule, and so you can say that a car IS-A Vehicule.


    Okie dokie, I'll be sure to write that down right away.



    Oliver Wong wrote:
    > "dugrocker" <> wrote in message
    > news:...
    >
    > > ArrayList<? extends A> bList; //The list should be a list of
    > > something
    > > //that either extends or
    > > is an A. B
    > > //Fullfills this
    > > requirement
    > >

    > [...]
    > >
    > > /* *********************************************************
    > > * The problem is here in the next line.
    > > *
    > > * Compiler message:
    > > *
    > > * The method add(capture-of ? extends A) in the type
    > > * ArrayList<capture-of ? extends A> is not applicable for the
    > > * arguments (B)
    > > *
    > > * *********************************************************/
    > > myContainer.bList.add(new B()); //(fails to compile)

    >
    > First of all, realize that when a class extends another class, there is
    > an IS-A relationship formed between the two classes. That is, if B extends
    > A, then for any given instance of B, you can say that that instance IS-A A.
    > This more intuitive if you use real class names. Let's say Vehicule and Car.
    > Car extends Vehicule, and so you can say that a car IS-A Vehicule.
    >
    > bList is an ArrayList<? extends Vehicule> which in informal terms means
    > it's a list of something which extends vehicule. Let's give that something a
    > name: call it S. Now you don't actually know what S is, only that S extends
    > Vehicule. So S could be Vehicule itself, or it could be Car, or it could be
    > some other class that extends Vehicule (such as Boat).
    >
    > You can never add anything to this list. Why? Because there's no way to
    > guarantee that whatever it is your adding extends S. In the above example,
    > you're trying to add Car to the list, but it's not clear that the list can
    > accept Car, because Car might not extend S. (e.g. Car doesn't extend Boat,
    > so if S is actually Boat, you couldn't add the Car to a list of boats)
    >
    > My guess is that you don't actually want an ArrayList<? extends
    > Vehicule>, but rather an ArrayList<Vehicule>. This is saying that you have a
    > list of vehicules. You can put a car in a list of vehicules, because a car
    > IS-A vehicule.
    >
    > - Oliver
     
    dugrocker, Aug 17, 2006
    #3
  4. dugrocker

    Oliver Wong Guest

    "dugrocker" <> wrote in message
    news:...
    > So, what are you saying, if you make the following statement,
    > "ArrayList<? extends A> aList;" you will be able to instantiate it as
    > an ArrayList<A> or ArrayList<subclass of A> but you will never be able
    > to add any objects to it?


    Right.

    >
    > This syntax, ArrayList<? extends A>, should only be used in a method
    > signature then, and not in a variable declaration?


    I don't know about that. It's mainly useful when you want to support all
    different kinds of list, and you don't plan on putting anything into the
    list, but only in extracting things from the list.

    - Oliver
     
    Oliver Wong, Aug 17, 2006
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. christopher diggins
    Replies:
    16
    Views:
    786
    Pete Becker
    May 4, 2005
  2. Øyvind Isaksen
    Replies:
    1
    Views:
    1,029
    Øyvind Isaksen
    May 18, 2007
  3. Ben
    Replies:
    2
    Views:
    955
  4. Lawrence D'Oliveiro

    Death To Sub-Sub-Sub-Directories!

    Lawrence D'Oliveiro, May 5, 2011, in forum: Java
    Replies:
    92
    Views:
    2,170
    Lawrence D'Oliveiro
    May 20, 2011
  5. gzinger

    How to bing a collection with sub-collection to grid

    gzinger, Jun 23, 2005, in forum: ASP .Net Datagrid Control
    Replies:
    11
    Views:
    316
    Jeffrey Tan[MSFT]
    Jul 5, 2005
Loading...

Share This Page