Java - 如何从超类列表中清晰地构造子类列表?

时间:2013-04-11 00:25:09

标签: java inheritance

具体来说,我有一个对象列表。该类对象的每个子类都与特定的功能相关联。

这是我对这个问题的天真解决方案,而且很难看:

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

我也试过这样的事情:

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

但无法使用:

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

我在这里注定了天真的代码吗?是否真的没有聪明的方法来接受超类对象列表并根据它们的实际类来处理它们?


以下是我要解决的问题:

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

1 个答案:

答案 0 :(得分:2)

正确的做法是使用基类型列表(List<SuperClass>)来使用多态。您不应该在遍历不同子类的循环中以不同方式处理它们。你应该做的是调用在超类(更好的是,接口)上定义的特定方法,并在每个子类(实现)中以不同方式实现该方法。见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();
}

秘诀在于定义不同实现的常见方面,并将它们全部压缩到相同的签名中。