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