Skip to content

How to avoid casting when accessing subclass variables from ArrayList of type superclass

public void heal() {
    HealingItem hItem = null;
    
    Iterator<Item> it = getInventory().show_inventory().iterator();
    while (it.hasNext()) {
        if (it.next().getHealing_item() == true) {
            hItem = (HealingItem) it.next();
        }
    }
}

I have a parent class Item, and a subclass HealingItem which extends that – for this method I want the player to be able to only access the HealingItem’s in the ArrayList of type Item.

Is there a more efficient method of performing this action which perhaps doesn’t involve continually casting for these types of issues, or is it even my design which may be faulty?

Thanks

Answer

Unfortunately, in Java you’re stuck with the “ceremony.” To fix your example per the discussion:

public void heal() {
    Iterator<Item> it = getInventory().show_inventory().iterator();

    while (it.hasNext()) {
        Item item = it.next();
        /*
         * item.getHealing_item() is true
         * implies item is instanceof HealingItem
         */
        if (item.getHealing_item()) {
            HealingItem hItem = (HealingItem) item;
            /*
             * Do something...
             */
        }
    }
}

In Java 11 you can reduce some of the ceremony with “var”:

public void heal() {
    var it = getInventory().show_inventory().iterator();

    while (it.hasNext()) {
        var item = it.next();

        if (item instanceof HealingItem) {
            var hItem = (HealingItem) item;
            /*
             * Do something...
             */
        }
    }
}

In Java 17 (preview feature as early as 14), you can use “enhanced” instanceof to combine the test with the cast:

public void heal() {
    var it = getInventory().show_inventory().iterator();

    while (it.hasNext()) {
        var item = it.next();

        if (item instanceof HealingItem hItem) {
            /*
             * Do something...
             */
        }
    }
}