【问题标题】:Returning an extended class返回扩展类
【发布时间】:2013-04-04 16:06:16
【问题描述】:

我不确定这是否真的有意义(我有点搞糊涂了),但我想做的是创建一个迷你游戏插件,我试图让它在地图之间循环,我创建了一个扩展 BaseGame 的新类,我将插件实例、世界名称和 xml 文件名传递给超类 BaseGame,然后 basegame 类解析来自 xml 文件和设置变量的信息。我在扩展 BaseGame 的类中有一些方法,因为大多数地图都有不同的游戏类型,所以我需要为不同的事件做不同的事情,例如在 TDM 上我需要阻止玩家打破这个,所以我想在监听器中这样做

@EventHandler
public void blockDestroy(BlockBreakEvent event) {
    plugin.mapCycler.getCurrentWorld().onBreakEvent(event);
}

我面临的问题是从 MapCycler 类返回当前世界,因为所有地图类都有不同的方法,我需要一种方法以通用方法返回地图类,该方法可以返回所有扩展 BaseGame 的地图类,但我仍然需要能够访问扩展 BaseGame 的类中的方法。

如果您需要更多说明,请告诉我。

谢谢

编辑 1:

在 BaseGame 类中,将在所有扩展 BaseGame 的 World 类中使用通用方法,例如,这些方法将在所有扩展 BaseGame 的类中使用

    public String getMapName() {
    return xmlFileReader.getMapName();
}


public String getMapObjective() {
    return xmlFileReader.getMapObjective();
}
    public void resetInventory(Player player) {
    player.getInventory().clear();
    player.getInventory().setArmorContents(null);
    player.setHealth(20);
    player.setFlying(false);
    player.setGameMode(GameMode.SURVIVAL);
    player.setFoodLevel(20);
}

并且在扩展 BaseGame 类的类中,它将具有与世界相关的独特方法,例如

public void blueWin() {
    Bukkit.getServer().broadcastMessage(Messages.colorize("Blue win - nice message in update"));
    for(String player : blueTeamList) {
        Player blue = Bukkit.getServer().getPlayer(player);
        resetInventory(blue);
        Packet206SetScoreboardObjective packet = new Packet206SetScoreboardObjective(plugin.relicWorld.sb.getObjective(plugin.relicWorld.name), 1);//Create Scoreboard create packet
        sendPacket(blue, packet);
        String loc = DatabaseManager.getLastLoc("SELECT * FROM ag_users WHERE user = \'" + blue.getName() + "\'");
        blue.teleport(LocationManager.stringToLoc(loc));
        Bukkit.getServer().dispatchCommand(Bukkit.getServer().getConsoleSender(), "eco give " + blue.getName() + " 250");   
    }
    for(String player : redTeamList) {
        Player red = Bukkit.getServer().getPlayer(player);
        resetInventory(red);
        Packet206SetScoreboardObjective packet = new Packet206SetScoreboardObjective(plugin.relicWorld.sb.getObjective(plugin.relicWorld.name), 1);//Create Scoreboard create packet
        sendPacket(red, packet);
        String loc = DatabaseManager.getLastLoc("SELECT * FROM ag_users WHERE user = \'" + red.getName() + "\'");
        red.teleport(LocationManager.stringToLoc(loc));
        Bukkit.getServer().dispatchCommand(Bukkit.getServer().getConsoleSender(), "eco give " + red.getName() + " 50"); 
    }
    Bukkit.unloadWorld(getWorld(), false);
    resetAll();
}

因为它是世界上独一无二的。

【问题讨论】:

  • 请发布一个示例,展示您可能需要在不同对象上调用哪些方法。常用的方法有哪些?
  • 我已经更新了我的帖子。

标签: java minecraft bukkit


【解决方案1】:

他们的关键是你需要为你的世界对象定义一个统一的接口。然后您可以调用相同的方法(在基类/接口中定义)并通过多态每个子类可以做出不同的反应

interface World{
    public void onBreakEvent(BlockBreakEvent e);
}

class World1 extends BaseGame implements World{
    public void onBreakEvent(BlockBreakEvent e) {
        System.out.println("Breaking from world 1")
    }
}

class World2 extends BaseGame implements World{
    public void onBreakEvent(BlockBreakEvent  e) {
        System.out.println("Breaking from world 2")
    }
}

现在当你调用plugin.mapCycler.getCurrentWorld() 时,它应该返回一个World 对象,也就是说,它实现了World 接口。每个对象的反应可能不同,但由于它们都共享接口,因此可以将它们视为相同。

plugin.mapCycler.getCurrentWorld().onBreakEvent(event);

【讨论】:

  • 跳过扩展 BaseGame 类的部分
  • @DCSoftware 通过实现World 接口,您仍然可以扩展BaseGame。不知道你的问题是什么......
  • 好的,我会尝试更清楚 - 我需要的是能够创建许多扩展 BaseGame 的类,这些类具有独特的方法,但我需要能够从一种方法返回所有类
  • @DCSoftware 看来你没听懂我的回答。如果没有讨厌的intanceofs 和强制转换,你不能从同一个地方调用不同类的不同方法。正确的方法是调用你的接口定义的方法。如果您需要它们对每个对象采取不同的行为,您可以使用我向您展示的多态行为
  • 我设法让它工作 - 谢谢。实际上我确实想到了 instanceof 方法来做到这一点,但它不是很有效,所以现在我正在使用接口方法..
【解决方案2】:

我认为您必须将返回类型定义为超类。然后你的方法可以返回从这个超类派生的任何类。

这被称为 java 中的协变返回类型。几个例子:sample1sample2

这是一个示例代码:

class A {
    int x = 1;
}

class B extends A {
    int x = 2;
}

class Base {    
    A getObject() {
        System.out.println("Base");
        return new B();
    }
}

public class CovariantReturn extends Base {

    B getObject() {
        System.out.println("CovariantReturn");
        return new B(); 
    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        Base test = new CovariantReturn();
        System.out.println(test.getObject() instanceof B);
        System.out.println(test.getObject().x);
    }
}

【讨论】:

  • 对不起,我不太明白
  • 链接中包含示例代码的详细解释
  • @JuanMendes:现在可以了吗?
  • 不确定答案是否满足 OP 的需求。但是,是的,现在这就是 SO 所期望的。也就是说,即使链接失效,它也可能对其他人有用。
猜你喜欢
  • 2011-06-25
  • 2021-11-12
  • 1970-01-01
  • 1970-01-01
  • 2012-01-18
  • 2015-11-06
  • 2018-04-06
  • 1970-01-01
  • 2022-11-25
相关资源
最近更新 更多