具体的Java继承查询 - 需要建议

时间:2014-03-02 14:01:51

标签: java inheritance

我遇到的问题非常具体,而且有点难以解释。如果您需要更多有关任何细节,请与我们联系我有一个名为System的抽象类。为了保存我的System个对象,我有一个SystemManager,其中包含System的列表,以及一些用于操作它的函数。里面包含:

List<System> systems = new ArrayList<System>();

现在,我想创建另一个抽象类,它是System的一种特定类型RenderSystem。这将继承自System,但还有一些功能。我还想创建一个RenderSystemManager,它应该完成SystemManager所做的一切,除了一些额外的功能。此外,我希望管理器中没有System列表,而是希望程序员不会在其中放置任何常规RenderSystem对象。我的初衷是继承System,只需将列表类型更改为SystemManger

RenderSystem

Java不允许这样做,因为系统类型为systems = new ArrayList<RenderSystem>(); 而不是System。考虑到RenderSystem继承自RenderSystem,我认为可以。我可以想到解决此问题的一种方法是将System中的所有代码复制并粘贴到SystemManager中,然后将代码行更改为:

RenderSystemManager

我的另一个本能是覆盖List<RenderSystem> systems = new ArrayList<RenderSystem>(); 函数以确保它只处理addSystem(System system),但程序员可能会认为即使它不起作用也允许它们执行。

RenderSystem

但这些似乎并不优雅。有人有什么建议吗?

3 个答案:

答案 0 :(得分:5)

您的经理与他们包装的列表具有相同的类型安全要求。因此,他们应遵循相同的策略,并且是通用类型:

public class BaseSystemManager<T extends System> {
    private List<T> systems = new ArrayList<>();

    public void addSystem(T system) {
        systems.add(system);
    }

    // common methods
}

public class SystemManager extends BaseSystemManager<System> {
    // methods specific to System handling
}

public RenderSystemManager extends BaseSystemManager<RenderSystem> {
    // methods specific to RenderSystem handling
}

答案 1 :(得分:0)

我认为你在addSystem调用中添加保护的第二直觉是正确的。这样,SystemManager仍然可以在系统列表上运行。但是,我会更改addSystem的实现,以指示开发人员正确使用:

@Override
public void addSystem(System system)
{
    if (system instanceof RenderSystem)
    {
        super.addSystem(system);
    }
    else
    {
        throw new IllegalArgumentException("Only RenderSystem objects can be added to a RenderSystemManager");
    }
}

答案 2 :(得分:0)

您的SystemManager可以有一个System对象列表,列表可以是私有的,将对象添加到该列表的唯一方法是只将RenderSystem作为参数的函数。你试图将泛型用于他们可能不合适的用途。

但我认为你有更大的问题。

我认为当我们开始尝试“从内到外”设计时,我们很多人都会遇到这种情况,即,您正在采用编程结构并尝试将它们串联在一起,忽略(或忘记)什么代码正试图从更高层次做。这就像是说“我想在一个do循环中有一个while循环,它有一个带有try-catch-finally-then的switch语句,但我不想嵌套所有这些该死的大括号。”

回过头来考虑一下你想要完成的外部功能,并从那里通过设计和实现细节的小步骤前进......