Search code examples
javainheritancesubclasssuperclass

Array of superclass objects. How to manage them as subclass ones?


Having these classes:

public abstract class Furniture

public class Chair : Furniture

public class Table : Furniture

public class Kitchen
{
ArrayList <Furniture> furnitures;
//other code
public void function ()
{
  Furniture furniture = furnitures.get();
  doSomethingInKitchen(furniture);
}


private void doSomethingInKitchen (Chair c);
private void doSomethingInKitchen (Table t);

}

I am looking for the best practice that assures me to manipulate the Superclass Furniture object as a subclass one (Chair or Table).

I tried with a simple cast, but when I call the function it operates with the Furniture Object, not with the Table or Chair one.

What I tried is something like:

for each Furniture in Array List
if(furniture.get() istance of Table)
{
currentFurniture = (Table) furniture.get();
}

else if (furniture.get() istanceof Chair)
{
currentFurniture = (Chair) furniture.get();
}
doSomethingInKitchen(currentFurniture)

I don't know if the problem is that currentFurniture is declared as

Furniture currentFurniture;

And so it won't be recognized as Chair or Table despite of the casting or if the design itself of the solution is wrong.


Solution

  • Your cast is lost as soon as your reassign it to the common variable. You need handle each type separately:

    for (Furniture furniture : furnitures) {
        if (furniture instanceof Table) {
            doSomethingInKitchen((Table)furniture);
        } else if (furniture instanceof Chair) {
            doSomethingInKitchen((Chair)furniture);
        }
    }
    

    Ideally though, you would avoid casting altogether and implement the differing logic on the subclass itself. For example:

    abstract class Furniture {
        abstract void doSomethingInKitchen();
    }
    
    class Table extends Furniture {
        @Override
        void doSomethingInKitchen() {
            // Table-specific logic
        }
    }
    
    class Chair extends Furniture {
        @Override
        void doSomethingInKitchen() {
            // Chair-specific logic
        }
    }
    

    Now in your Kitchen you just do

    for (Furniture furniture : furnitures) {
        furniture.doSomethingInKitchen();
    }