【问题标题】:Java - Randomly moving down a class hierarchyJava - 随机向下移动类层次结构
【发布时间】:2026-01-11 07:30:01
【问题描述】:

我目前正在开发一个“物品掉落”系统,其中物品(及其属性)是在杀死敌人时随机生成的。我拥有的当前系统是类的层次结构,Item 是根超类。每个类都有所有子类共有的特定属性。

理想情况下,在删除项目时,程序会随机选择项目的一个属性并相应地向下移动层次结构树。例如,流程如下:

| 随机选择的属性确定树中的路径:

物品 | ItemType -> Equipable |装备类型 -> 武器 |武器类型 -> 等

示例代码:

abstract class Item 
{   
    private Type itemType;
    private String itemName;
    private int itemLevel;
    private Rarity itemRarity;
    private boolean questItem;
    private int itemPrice;

    public Item(String name)
    {
        itemType = Type.randomize();
        itemName = name;
        itemLevel = randomizeLevel(pLvl, eLvl);
        itemRarity = Rarity.randomize(bonus, pLvl, eLvl, iLvl);
        questItem = false;
        itemPrice = determinePrice();
    }
}

Type 是一个枚举,决定了层次结构中的下一个级别。有了这个系统,我不知道如何让程序确定下一个级别,然后继续进行。

我遇到的问题是,我已经意识到,为了让它发挥作用,我必须从层次结构的底部向上工作。有没有办法让我从上到下工作,这意味着我可以从一个基本的 Item 类开始,然后按程序向下工作(使用我创建的方法来随机选择属性)。

如果没有,我有什么具体的方法可以实现这个系统吗?

【问题讨论】:

  • 为什么你认为你必须从层次结构的底部向上工作?
  • 当然可以。有什么问题?
  • @DavidK 我遇到的问题是,确定层次结构中下一个级别的属性是在类本身的构造函数中确定的。因此,就像现在一样,一旦确定了下一条路径,我不知道如何向下移动层次结构。我会更新问题
  • 选择随机子类的代码可以在调用您要创建的对象的构造函数之前执行。当您随机选择一个类时,您就可以构建它。至少有两个答案基于此。

标签: java hierarchy


【解决方案1】:

您可以从枚举类中获取所有枚举的列表 - 顺序是声明它们的顺序,因此如果您按层次顺序声明它们,您可以随意遍历列表。相关的 oracle 文档在这里:

https://docs.oracle.com/javase/tutorial/reflect/special/enumMembers.html

【讨论】:

  • 我知道这很有用,但你能详细说明我将如何使用它吗?
  • @GBoggs 该调用以层次结构顺序为您提供整个层次结构。因此,在列表中找到您的项目。想升职?从该索引上移列表。想向下移动?在列表中进一步选择一些东西。这样你就可以得到保持层次结构的随机化。
【解决方案2】:

如果您想自上而下地工作,特别是如果子类的选择取决于构建超类时所做的选择,那么支持组合可能比继承要好得多。因此,如果对于 Item 你有 Type 的特定信息,你可以让 Type 包含你可能想要的所有属性,包括对这个(概念)层次结构中后续对象的引用。

当然,在任何时候,只要您在创建对象之前知道它应该是特定的子类,您就可以另外从ItemType 等中创建一个小的类层次结构。否则,合成将是按照您描述的方式创建项目的唯一方法。

【讨论】:

    【解决方案3】:

    您可以在每个类中使用一个静态方法来确定“下一个转换”(将“项目”的包视为一棵树。

    所以

    // untested code
    
    String nextClass = "Item";
    
    // define a helper method
    
    Class x = getClass(nextClass);
    
    while( x.hasMore() == true )
    {
        nextClass = x.getNextClass();
        x = getClass(nextClass);
    
    } 
    // reflection here on Class 'x' (whatever that is...)
    

    然后你可以使用反射来实例化最后一个类。

    这可能是个坏主意。但它会“走”一棵结构良好的类树

    【讨论】:

      【解决方案4】:

      如果我理解您的目标,并尝试重新表述:

      • 你有一个*类型:项目

      • 通过添加一些属性,您拥有(或现在创建,或者可能进一步?)Item 的子类:Equipable,然后是 Weapon,等等。

      • 从顶部(项目),你想随机选择一个子类(装备?是/否?如果是=>装备类型等。

      我的建议:

      • 不要打破子类的概念:父母不需要提前知道他的孩子

      • 然后取一个类(第一个:item,依此类推),通过反射搜索子类

      • 在子级之间选择:此时您必须定义如何在子级之间进行分类:任何新变量,或任何以前缀开头的变量。例如,可以定义 final static int category_weapon=1; (或真、假、...)

      • 然后进行迭代,从顶部开始,获取子项,获取这些静态变量和值,然后在这些子项之间随机选择,然后再做一次

      另一种表征方式:使用接口(武器,可装备,...):好处是您可以应用预定义的方法(用于武器,...)

      更便宜:不使用任何变量,只需使用子类的名称来选择下一个。

      选择的好方法:准确定义您将如何处理这些对象。

      希望对你有帮助。

      【讨论】:

      • 所以你只是暗示我只有一个方法可以随机选择第一个属性(类型),然后有一个 switch 语句将相应地向下移动层次结构并随机选择下一个,所以依此类推,直到我到达底部节点之一?然后在那一点上我只是创建了那个对象?这是一种有效的方式,还是唯一的方式?
      • 这肯定不是最有效的方法,因为反射(但你的程序可以做一次,并缓存信息),而且它不是唯一的方法。主要的好处是类之间的独立性:当你在武器下创造一把匕首或一把刀的那一天,就完成了!你不必维护两个平行的结构(有一天,它不会是连贯的)。
      • 两件事。 1)你所说的类之间的独立性是什么意思? 2)你说的在下面创建匕首或刀是什么意思?
      • 假设你的应用使用了武器。下个月你想用一个新的子类来完善这个:刀。然后只有子类:没事多随机选择它。下个月:武器的其他子类:匕首:同上。