EagleOne
EagleOne

Reputation: 571

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.

Upvotes: 6

Views: 3721

Answers (2)

Priyamal
Priyamal

Reputation: 2969

since you are inheriting Furniture class theres no need of implementing 2 methods for each chair and Table

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

you can have a single method like this

private void doSomethingInKitchen (Furniture f);

and you can getRid of the casting in forloop and let the method do the casting.

private void doSomethingInKitchen (Furniture f){

   if(f instanceof Table){
   //code for the table 
   }else{
   //code for the chair
   } 

}

Upvotes: 2

shmosel
shmosel

Reputation: 50716

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();
}

Upvotes: 5

Related Questions