2013-04-11 78 views
0

具体来说,我有一个对象列表。该类对象的每个子类都与一个特定的功能相关联。Java - 如何从超类的列表中干净地构造子类的列表?

这是我天真地解决了这个问题,这是丑陋:

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

回答

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

秘诀是定义什么是不同的实现的通用特性,能够将它们全部挤入相同的签名。

+0

“能够将它们全部挤入相同的签名”正是这里不适合我的东西。每个类代表一个命令,所以我所调用的是基于它的类。 – Jeremy 2013-04-11 00:56:42

+0

@Jeremy应该有可能。发布一个简单的示例,说明您实际正在尝试做什么,并且有人可能会建议如何让代码具有多态性。打开对象的类型**真的**在OO圈子里皱起了眉头 – 2013-04-11 01:00:03

+0

编辑添加一个例子。希望很明显。这个问题正在为处理者找到合适的成果。 – Jeremy 2013-04-11 01:10:50