How to tell which subclass we used?

O

Ook

This is a textbook assignment: I have a class, Item. I have subclasses, CD
and DVD.

public class Item
{...}

public class DVD extends Item
{...}

public class CD extends Item
{...}

So when I create an instance of Item, I do this:

Item cd = new CD();

Question. When I iterate my Item collection, how can I tell whether an
instance is CD or DVD? Is there a native way to do this, some property of
Item, or do I need to create a property in Item that identifies it as a DVD
or CD instance?
 
O

Ook

This is a better question then the original. Given a class Item where CD and
DVD are subclasses. I do this:

public ArrayList<Item> List = new ArrayList<Item>();

And I add several the following to my ArrayList, List, so I have an
ArrayList of items of both CDs and DVDs.

Item cd = new CD();
Item dvd = new DVD();

To get a list of CDs only, I do this:

ArrayList<Item> list1 = new ArrayList<Item>();
for( Item item: List)
{
if( item instanceof CD)
list1.add( item );
}
return list1 ;

This works. Question - is this the most effecient way to do this, is there a
better way to return a list of Items of type CD only?
 
L

Lew

Ook said:
This is a better question then the original. Given a class Item where CD and
DVD are subclasses. I do this:

public ArrayList<Item> List = new ArrayList<Item>();

And I add several the following to my ArrayList, List, so I have an
ArrayList of items of both CDs and DVDs.

Item cd = new CD();
Item dvd = new DVD();

To get a list of CDs only, I do this:

ArrayList<Item> list1 = new ArrayList<Item>();
for( Item item: List)
{
if( item instanceof CD)
list1.add( item );
}
return list1 ;

This works. Question - is this the most effecient way to do this, is there a
better way to return a list of Items of type CD only?

For the suggested schema, wherein CD and DVD classes each inherit from Item,
and ones like it, the trick is never to ask an Item which kind it is. In other
words, the whole point of declaring a List or variable to hold type Item is
that you no longer explicitly care which subclass is in there at runtime.

If you need a List of CD, then declare it List<CD>. If you need a List of
Items that have to all be of only one subtype, e.g., all CDs or all DVDs, but
not a mix of both in the same list, declare it List<? extends Item>. If you
want a list of Items, and you can mix or match which kind of items, then
declare a List<Item>.

Why do I say that you do not care which kind of item it is, and thus recommend
that you never call "if ( item instanceof ...)"?

Because you likely only want the Item to do something all Items can do, just
differently. For example, suppose you wanted to know the maximum capacity in
bytes of your CD or DVD, but didn't know which.

Item item = getItemThatIsReallyOfASubtype();
int capacity = item.getCapacity();

Notice that this snippet does not need to know what subtype the item is
instanceof. 'item' knows its own type, so the invoking code doesn't need to.

Google "polymorphism" in object-oriented programming.

Usually if you are explicitly asking an object its runtime type you have
missed a better way to solve the actual problem. If you decide you need the
enumeration of subtypes, and less likely, if you are correct in that
assessment, you incur the maintenance surcharge of code changes every time the
inheritance hierarchy changes. (Which for some applications is never.)

Polymorphic approaches work even if someone else extends the class with a
subtype the original supertype designer never thought of in an application the
original supertype designer never thought of.

Ask yourself what you need to do with the returned list or value in your
snippet, and how you might solve that problem without explicit subtype
knowledge in the invoking code.

- Lew
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,024
Latest member
ARDU_PROgrammER

Latest Threads

Top