在 Java 中查找属于给定类型 Child 的所有 Objects
Finding All Objects that are a Child of a Given Type in Java
我目前正在编写一个 grid-based 益智游戏,遇到了 运行 个问题。
我有一个抽象的 Sprite class,其中每个 Sprite 代表我地图上的一些 object(玩家、墙等)。这个 Sprite class 有 children (Item, Entity, Obstacle),而这些 children 有 children (Item 有 InventoryItem 和 InstantUseItem),等等。只有 children 没有任何进一步的 children 不是抽象的,所以你只能实例化你能找到的具体 objects in-game (你可以实例化 Sword 和 Arrow,但不能实例化 Weapon - 他们的 parent object).
我的问题是我将所有 objects 存储在 Sprite ArrayList 中的 Tiles(每个地图都有宽度*高度的 Tiles)上,现在我想做一些事情,比如找到播放器的哪个 Tile object 开启,或找到所有包含敌人 object(或继承自它们的 class)的图块。
问题是,据我所知,我不能在我的 Map 或 Tile 中做类似的事情 object:
public ArrayList<t> findAllSpritesOfType(Type t) {
ArrayList<t> sprites = new ArrayList<t>();
for(Sprite s : this.getSprites()) {
if(s instanceof t) {
sprites.add((t) s); //Add after casting to right class
}
}
return sprites;
}
即使我尝试在 Sprite 中实现静态函数,我也需要这个(在所有 Sprite children 中的一种 'automatic covariance'):
public static ArrayList<this.Type> getSpritesOnTile(Tile t) {
ArrayList<this.Type> sprites = new ArrayList<this.Type>();
for(Sprite s : t.getSprites()) {
if(s instanceof this.Type) {
sprites.add((this.Type) s); //Add after casting to right class
}
}
return sprites;
}
我想到的其他方法有:
- 使后一种方法return成为精灵数组,然后使用协方差在所有children到returnchildren数组中覆盖此方法。
- 让 Sprite 包含 isWeapon()、isItem()、isEntity() 等(所有 return 为 false)然后在适当的 children 中覆盖这些方法。我现在使用这些方法而不是统一的 isGivenType(Type t) 方法或统一的静态 Type.isGivenType() 方法。
确保我的程序符合 Object 面向原则,并且易于扩展,这对这个项目来说非常重要。有什么方法可以实现我的任何解决方案,或者实现我的目标吗?
看来这就是你想要的:
public <T extends Sprite> ArrayList<T> findAllSpritesOfType(Class<T> clazz) {
ArrayList<T> sprites = new ArrayList<>();
for(Sprite s : this.getSprites()) {
if(clazz.isInstance(s)) {
sprites.add((T) s);
}
}
return sprites;
}
然后你可以这样使用它:
List<Item> items = findAllSpritesOfType(Item.class);
另一种方法是return流而不是列表:
public <T extends Sprite> Stream<T> findAllSpritesOfType(Class<T> clazz) {
return getSprites().stream().filter(clazz::isInstance).map(clazz::cast);
}
我目前正在编写一个 grid-based 益智游戏,遇到了 运行 个问题。
我有一个抽象的 Sprite class,其中每个 Sprite 代表我地图上的一些 object(玩家、墙等)。这个 Sprite class 有 children (Item, Entity, Obstacle),而这些 children 有 children (Item 有 InventoryItem 和 InstantUseItem),等等。只有 children 没有任何进一步的 children 不是抽象的,所以你只能实例化你能找到的具体 objects in-game (你可以实例化 Sword 和 Arrow,但不能实例化 Weapon - 他们的 parent object).
我的问题是我将所有 objects 存储在 Sprite ArrayList 中的 Tiles(每个地图都有宽度*高度的 Tiles)上,现在我想做一些事情,比如找到播放器的哪个 Tile object 开启,或找到所有包含敌人 object(或继承自它们的 class)的图块。
问题是,据我所知,我不能在我的 Map 或 Tile 中做类似的事情 object:
public ArrayList<t> findAllSpritesOfType(Type t) {
ArrayList<t> sprites = new ArrayList<t>();
for(Sprite s : this.getSprites()) {
if(s instanceof t) {
sprites.add((t) s); //Add after casting to right class
}
}
return sprites;
}
即使我尝试在 Sprite 中实现静态函数,我也需要这个(在所有 Sprite children 中的一种 'automatic covariance'):
public static ArrayList<this.Type> getSpritesOnTile(Tile t) {
ArrayList<this.Type> sprites = new ArrayList<this.Type>();
for(Sprite s : t.getSprites()) {
if(s instanceof this.Type) {
sprites.add((this.Type) s); //Add after casting to right class
}
}
return sprites;
}
我想到的其他方法有:
- 使后一种方法return成为精灵数组,然后使用协方差在所有children到returnchildren数组中覆盖此方法。
- 让 Sprite 包含 isWeapon()、isItem()、isEntity() 等(所有 return 为 false)然后在适当的 children 中覆盖这些方法。我现在使用这些方法而不是统一的 isGivenType(Type t) 方法或统一的静态 Type.isGivenType() 方法。
确保我的程序符合 Object 面向原则,并且易于扩展,这对这个项目来说非常重要。有什么方法可以实现我的任何解决方案,或者实现我的目标吗?
看来这就是你想要的:
public <T extends Sprite> ArrayList<T> findAllSpritesOfType(Class<T> clazz) {
ArrayList<T> sprites = new ArrayList<>();
for(Sprite s : this.getSprites()) {
if(clazz.isInstance(s)) {
sprites.add((T) s);
}
}
return sprites;
}
然后你可以这样使用它:
List<Item> items = findAllSpritesOfType(Item.class);
另一种方法是return流而不是列表:
public <T extends Sprite> Stream<T> findAllSpritesOfType(Class<T> clazz) {
return getSprites().stream().filter(clazz::isInstance).map(clazz::cast);
}