Java,如何基于其中一个接口重新构建对象?

时间:2016-02-20 23:49:30

标签: java interface casting

我有一组实现接口PaintableTickable的类。 另一个类World通过将它们推入ArrayList<Tickable>来跟踪其中的一些类。

我有一个不同的类适用于Paintable的所有对象,获得所有这些对象的可靠方法是使用getPaintables()方法向全世界询问,因为{保持所有对象{1}}都是可选择的和可绘制的。

当我尝试将World个对象转换为Tickable这样的对象时,问题就出现了:

Paintable

这导致:

    for (Paintable p : (ArrayList<Paintable>)world.getPaintables()) {
        // Do stuff
    }

是否有可能通过其他方式来解决这个问题?我可以,当然复制 error: incompatible types: ArrayList<Tickable> cannot be converted to ArrayList<Paintable>. 中的ArrayList,一个World,另一个Paintable,但这对我来说似乎很麻烦。

我希望这是有道理的。

5 个答案:

答案 0 :(得分:1)

我认为“修复”这个最简单的方法就是创建一个通用界面并将其用于所有列表。如果你所说的所有课程都同时实现了TickablePaintable,那么你可能应该这样做。

public class TickAndPaint
{
   public static void main(String[] args) {
      ArrayList<TickableAndPaintable> list = new ArrayList<>();
      for( Paintable t : list ) {
      }
      for( Tickable t : list ) {
      }
   }
}

interface Paintable {}
interface Tickable {}
interface TickableAndPaintable extends Paintable, Tickable {}

答案 1 :(得分:1)

根本不需要进行类型转换。在Iterable<Paintable>上实施Iterable<Tickable>World,然后您只需执行for(Paintable p : world)for(Tickable t : world)两者都可以在没有类型转换的情况下运行。

答案 2 :(得分:1)

一个不需要更改类/接口层次结构的替代方法是在List类中声明World容器,其中bounded type parameter具有多个边界。例如:

class World<T extends Object & Paintable & Tickable> {

    private List<T> tickablePaintables = new ArrayList<>();

    /*...*/

    public List<T> getTickablePaintables() {
        return tickablePaintables;
    }
    /*...*/       
}

然后在客户端代码中,您可以遍历World返回的tickable-paintable列表而不进行转换:

public <T extends Object & Paintable & Tickable> void doSomething() {

    World<T> w = new World<>();

    for (Tickable tickable : w.getTickablePaintables()) {
        //...
    }            
    for (Paintable paintable : w.getTickablePaintables()) {
        //...
    }            
}

由于类型参数在Java中的工作方式,不幸的是,这会在类/方法声明中添加一些混乱(用于声明T)。

答案 3 :(得分:0)

我没有完全回答你的问题,但我会试一试。

如果world.getPaintables()返回List,则表明您的代码无效。

如果world.getPaintables()同时拥有两者,那么像路易斯所说的那样,可以做一些可勾选和可绘制的对象:

for (Object p : (ArrayList<Object>)world.getPaintables()) {
    if (p instanceof Paintable)
        paint();
    else if  (p instanceof Tickable)
        tick();
}

答案 4 :(得分:0)

什么数据类型确实返回world.getPaintables()? 如果该方法的返回是Paintable的ArrayList,则不应该转换任何内容。 无论如何,你可以做类似的事情:

for(Object p : world.getPaintables()) {
    if(p instanceOf Paintable){
       (Paintable)p ... (do something);
    }
}

希望它对你有所帮助。