0

我以前从未在 Java 中遇到过此类问题。所有这些代码和完整的项目都可以在我的 GitHub 上找到。我有一个Snowflake具有类层次结构的类:

Snowflake extends SolidRectangle extends Movable extends Drawable extends Object

我班级中的以下两个代码部分在Snowflake我的游戏中产生了不同的图形结果:

//In Snowflake class
public void decay()
{
    age++;
    color = randomSnowflakeColor();
    if(age == 5)
    {
        super.remove();
        Snowflake.Mempool.returnSnowflake(this);
    }
}

//In Snowflake class
public void decay()
{
    age++;
    color = randomSnowflakeColor();
    if(age == 5)
    {
        this.remove();
    }

public void remove()
{
    super.remove();
    Snowflake.Mempool.returnSnowflake(this);
}

既不SolidRectangle也不Movable覆盖该remove方法,但Drawable使用以下实现:

//In Drawable class
public void remove()
{
    game.remove(this);
}

GameContent game具有以下实现:

//In GameContent class
public synchronized void remove(Drawable drawable)
{
    removeQueue.add(drawable);
}

我将为您省去详细信息removeQueue,只要说这正是您所期望的就足够了。

至于Snowflake.Mempool,我知道手动内存管理通常不是 Java 程序员的一部分,但我发现创建和垃圾收集这些雪花的开销太大,所以我想我会重用旧的雪花来避免这种开销。请不要为此分心。我的问题是关于前两个代码块如何可能不同,当它们看起来功能相同时。

那么,前两个代码块如何产生不同的结果呢?

4

3 回答 3

1

虽然调用 时预期的结果相同,但当从代码中的其他decay()位置调用时,可能会导致类的不同行为。remove()

使用您的 IDE,搜索该remove()方法的用法,所有可能都会显示出来。

于 2012-08-03T03:46:59.587 回答
1

在评论中你说:

删除由 CollisionHandler 调用,该处理程序将其识别为 SolidRectangle 并将其称为 ((SolidRectangle) snowflake).remove(),因此它调用 Drawable 版本而不是代码的 Snowflake 版本。

我不认为这是一个正确的解释。

你似乎在说这个:

Snowflake snowflake = ...
((SolidRectangle) snowflake).remove();

将导致SolidRectangle.remove()在雪花上调用被覆盖的方法。这是不正确的。一旦方法被覆盖,它就不能被调用SnowflakeSnowflake方法(或Snowflake超类型方法)调用super.remove()

于 2012-08-03T04:02:02.893 回答
0

我想到了。问题在于,由于Snowflake.Mempool充当堆栈,因此最近销毁的雪花用于制作新的雪花。我将所有Drawable元素保存在一个ArrayList<Drawable>. 这种组合导致某些雪花出现两次,ArrayList<Drawable>从而破坏了我的帧调整算法。切换到aHashSet<Drawable>解决了这个问题。

于 2012-08-03T04:32:48.487 回答