我以前从未在Java中遇到过这种问题。所有这些代码和完整项目都可以在my 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程序员当天的一部分,但我发现在创建和垃圾收集这些雪花时有太多的开销,所以我想我会重用旧雪花避免这种开销。请不要分心。我的问题是关于两个第一个代码块在功能上是否相同时可能会有什么不同。
那么,两个第一个代码块怎么能产生不同的结果呢?
答案 0 :(得分:1)
虽然在调用decay()
时会出现相同的结果,但在代码中从其他地方调用remove()
时,可能会导致类的不同行为。
使用您的IDE,搜索remove()
方法的用法,并且可以显示所有用法。
答案 1 :(得分:1)
在评论中你说过:
remove由CollisionHandler调用,它将其识别为SolidRectangle并将其称为((SolidRectangle)雪花).remove(),因此它调用了Drawable版本而不是Snowflake版本的代码。
我认为这不是一个正确的解释。
你似乎在说这个:
Snowflake snowflake = ...
((SolidRectangle) snowflake).remove();
会导致在雪花上调用重写的SolidRectangle.remove()
方法。那是不对的。覆盖该方法后,除Snowflake
方法(或Snowflake
超类型方法)调用Snowflake
外,无法在super.remove()
上调用该方法。
答案 2 :(得分:0)
我明白了。问题是,由于Snowflake.Mempool
充当堆栈,最近被破坏的雪花被用来制造新的雪花。我将所有Drawable
元素保存在ArrayList<Drawable>
中。这种组合导致某些雪花在ArrayList<Drawable>
中出现两次,从而破坏了我的帧调整算法。切换到HashSet<Drawable>
解决了问题。