Java:所有派生类必须实现的抽象或通用列表

时间:2016-01-09 17:59:11

标签: java generics inheritance arraylist collections

我正在为Java游戏引擎制作一个基于组件的系统。

我有不同的系统类来处理不同的事情,例如PhysicsSystem,RenderSystem,EditorSystem等。所有类都继承自BaseSystem,而BaseSystem又实现了一个接口ISystem。

我希望我的所有系统类都有一个ArrayList,但每个系统类中的类型可能不同,这意味着RenderSystem可能有一个RenderComponents列表,而PhysicsSystem有一个PhysicsBodyComponents列表。

是否可以在BaseSystem类或ISystem接口中定义所有派生类随后实现的泛型或抽象列表?我对泛型有一点经验,所以我对此感到有点困惑。

这是我目前的代码。如您所见,我为派生类创建了第二个列表,这是一种浪费。

interface ISystem
{
    boolean AddToSystem(Component c);
}

abstract class BaseSystem implements ISystem
{
    // can I make this list generic, so it can store any type in derived classes?
    // e.g., Component, IRenderable, IPhysics, etc.
    protected List<Component> _componentList;
}

class RenderSystem extends BaseSystem
{

    //  need to make a second list that stores the specific render components
    List<IRenderable> _renderList = new ArrayList<IRenderable>();

    void Update()
    {
        for (IRenderable r : _renderList)
            r.Render(); // this code is specific to the IRenderable components
    }

    @Override
    public boolean AddToSystem(Component c)
    {
        boolean succesfullyAdded = false;

        if (c instanceof IRenderable)
        {
            succesfullyAdded = true;
            _renderList.add((IRenderable) c);

        } else
            throw new RuntimeException("ERROR - " + c.Name() + " doesn't implement IRenderable interface!");

        return succesfullyAdded;

    }
}

2 个答案:

答案 0 :(得分:3)

当然,假设所有组件都实现IComponent,请使用以下内容:

interface ISystem<ComponentType extends IComponent> {
   public boolean AddToSystem(ComponentType c);
}

如果您不想拥有硬类型依赖项,则可以删除extends IComponent,但这会使处理系统列表更加困难。

答案 1 :(得分:1)

我认为你需要这样的东西

private static abstract class AbstractClass<T> {

    final List<T> objects = new ArrayList<T>();
}

private static class ComponentHolder extends AbstractClass<Component> {

    public void add(final Component c) {
        objects.add(c);
    }

    public Component getComponent(final int index) {
        return objects.get(index);
    }
}

在您的示例中,它将是这样的:

abstract class BaseSystem<T> implements ISystem
{
    protected List<T> _componentList = new ArrayList<T>();
}

class RenderSystem extends BaseSystem<IRenderable>
{
    void Update()
    {
        for (IRenderable r : _componentList)
            r.Render(); // this code is specific to the IRenderable components
    }

    @Override
    public boolean AddToSystem(Component c)
    {
        boolean succesfullyAdded = false;

        if (c instanceof IRenderable)
        {
            succesfullyAdded = true;
            _componentList.add((IRenderable) c);

        } else
            throw new RuntimeException("ERROR - " + c.Name() + " doesn't implement IRenderable interface!");

        return succesfullyAdded;

    }
}