当创建两个或多个类的引用时,可销售菜单工具包字段会更改(使用GitHub)

时间:2015-03-27 22:01:02

标签: java minecraft bukkit

我最近在我的Spigot / Bukkit插件中遇到了一个奇怪的错误,这完全没有任何意义。请注意,这个问题可能很长,因为我正在处理的项目相当大,因为源代码(下面提供)包含不包含在这里的类,我将尽力描述我的问题。 / p>

在Minecraft中,使用Bukkit API,您可以创建图形菜单(GUI' s),您可以在其中放置某些插槽中的项目,单击时,您可以调整功能。

就我而言,我创建了Menu基础类,其中包含创建此类菜单的基本方法。然后,扩展Menu类的PurchaseMenu用于触发特定位置的功能,以模拟可从菜单中单击的产品的事务。

深入地说,我将包含的菜单包含" Kit"显示(如游戏类),当一个左键单击显示玩家可以购买它,或者如果它已经购买,玩家将只选择该套件使用。当一个右键单击显示时,播放器可以将套件升级到3个。

在这两种情况下,都必须弹出一个交易菜单,以便购买或升级点击的套件。通过在每个PurchaseMenu类的构造函数中传递单击的工具包,我的设计非常简单。

上述所有问题都是套件从构造函数中正确传递,但实际购买或升级的套件是随机的(显然不是,但尚未找到任何证据)而且这通常会在一些尝试之后发生。

我的设计:

  • 每个Menu类包含两种方法。单击菜单显示(交互)时会调用InventoryClick。在创建(打开)菜单时调用InventoryConstruct
  • Purchase Menu类也包含两个方法。成功购买显示器时会调用PurchaseProductPrePaymentChecks是在购买前需要运行的必要检查。

我的问题:

  • 如何修补该问题,并将正确的套件保存在班级的私人字段中?
  • 如何在某些项目中改进我的设计(方法)以避免此类问题?

感谢任何形式的帮助,我希望我详细描述了我的问题,如果您需要任何进一步的源代码,请在下面发表评论。

更新

由于问题将超过30k字符,我将整个项目上传到Git存储库。

https://github.com/parat26/core

Menu.java https://github.com/parat26/core/blob/master/src/src/ares/core/menu/Menu.java

PurchaseMenu.java https://github.com/parat26/core/blob/master/src/src/ares/core/menu/PurchaseMenu.java

BattleOptionsMenu.java https://github.com/parat26/core/blob/master/src/src/ares/core/menu/type/MenuBattleOptions.java

PurchaseMenuKit.java https://github.com/parat26/core/blob/master/src/src/ares/core/menu/type/PurchaseMenuKit.java

1 个答案:

答案 0 :(得分:2)

尝试将PurchaseMenu.object更改为final并查看输出结果。此外,System.out.println()是您的朋友。

我建议您不要在工具包中使用Object,因为在将object设置为sellableKit时可能会更改对象。创建一个名为Sellable<T>的接口,以便您可以使用以下命令强制执行该类型(称为强类型)

private final ItemStack item;
protected final Sellable<? super Kit> kit;
private final GoldCurrency currency;

public PurchaseMenu(String menuName, ItemStack sellableItem, Sellable<? super Kit> sellableKit, GoldCurrency currencyType)
{
    super(Material.STONE, menuName, 54);

    item = sellableItem;
    kit = sellableKit;
    currency = currencyType;

    DependOnEvents(true);
}

将这些字段设为最终也是一种很好的做法,因为在创建对象后不会显示您正在设置这些字段,并且任何人都可以立即知道这些对象永远不会更改。它也应该启发这种情况,因为最终的对象无法改变。

您应该从private Kit kit;删除BuyKitOwnershipMenu字段,因为您只需复制该对象。您的PurchaseProduct()方法可以更改为

@Override
    public void PurchaseProduct(GoldCurrency currency, Client client)
    {
        client.getManager().setKitOwned(kit, true);
    }

因为套件现在受到保护并且在超级类中。