0

Specifically, I have a list of objects. Each subclass of that class of objects is associated with a specific piece of functionality.

Here is my naive solution to this problem, and it is ugly:

List<SuperClass> superClasses = ...

List<Subclass1> obj1 = Lists.newArrayList();
List<Subclass1> obj2 = Lists.newArrayList();
List<Subclass1> obj3 = Lists.newArrayList();
List<Subclass1> obj4 = Lists.newArrayList();
...

for (SuperClass obj : superClasses) {
  if (obj.getClass().equals(Subclass1.class)) {
    obj1.add((Subclass1) obj);
  }
}

//repeat for each subclass

I also tried something like this:

public Map<Class, List<SuperClass>> constructMap(List<SuperClass> superClasses);

but this couldn't be used:

(List<Subclass1>) constructMap(superClasses).get(Subclass1.class)
cannot cast from List<SuperClass> to List<Subclass1>.

Am I doomed to the naive code here? Is there really no smart way to take in a list of super-class objects and handle them based on their actual class?


Here is the problem I am trying to solve:

public Driver {

    List<Fruit> fruits = collectAllFruit();

    StemHandler.pullStem(fruitsThatAreApples, fruitsThatArePears);
    ColorHandler.getColor(fruitsThatAreApples, fruitsThatAreOranges, fruitsThatArePears);


public interface Fruit {

    getColor();
}

public class Apple implements Fruit {

    getColor();
    pullStem();
}

public class Orange implements Fruit {

    getColor();
    peel();

}

public class Pear implements Fruit {

    getColor();
    pullStem();

}


public interface FruitHandler {


}

public class StemHandler extends FruitHandler {

    pullStem(List<Apple>, List<Pear>)

}

public class ColorHandler extends FruitHandler {

    getColor(List<Apple>, List<Orange>, List<Pear>)
}
Jeremy
  • 5,365
  • 14
  • 51
  • 80

1 Answers1

2

The correct thing is to use polymorphism using your list of the base type (List<SuperClass>). You shouldn't handle them differently in your loop that iterates through the different sub classes. What you should do is call a specific method that is defined on the super class (better yet, an interface) and implement the method differently in each sub class (implementation). See Returning an extended class

interface MyInteface{
    public void doSomething();
}

class Sub1 implements MyInterface{
    public void doSomething() {
        System.out.println("Behavior # 1");
    }
}

class Sub2 implements MyInterface{
    public void doSomething() {
        System.out.println("Different Behavior");
    }
}

for (MyInteface obj : superClasses) {
    // Will do different things for different implementations
    obj.doSomething();
}

The secret is to define what are the common aspects of the different implementations and be able to squeeze them all into the same signature.

Community
  • 1
  • 1
Ruan Mendes
  • 90,375
  • 31
  • 153
  • 217
  • The "be able to squeeze them all into the same signature" is exactly what doesn't work for me here. Each class represents a command, so what I'm calling is based on what class it is. – Jeremy Apr 11 '13 at 00:56
  • @Jeremy It should be possible. Post a simplified example of what you are actually trying to do and someone could suggest how to make your code polymorphic. Switching on the type of an object is **really** frowned upon in OO circles – Ruan Mendes Apr 11 '13 at 01:00
  • Edited to add an example. Hopefully it is clear. The issue is getting the right fruits for the handlers. – Jeremy Apr 11 '13 at 01:10
  • @Jeremy It's hard to tell what `StemHandler.pullStem(fruitsThatAreApples, fruitsThatArePears);` is doing. Your example doesn't make a lot of sense in my head, it's unclear what its purpose is. If you're not going to treat them as a single object, you should stick to your idea of having separate arrays for each type and not pretending they are the same type. But I still think you should be able to do it. I'll take another look here tomorrow`. Make sure you define the return types on your singatures so we can make more sense of the code – Ruan Mendes Apr 11 '13 at 01:21
  • Here's another example of how to convert from `instanceof` to polymorphism https://gist.github.com/oldbag/2409067 – Ruan Mendes Apr 11 '13 at 16:23