【问题标题】:Comparing Enum Entries - Java比较枚举条目 - Java
【发布时间】:2017-04-09 15:54:14
【问题描述】:

假设我有几台机器:

//Test code of course.
public class Start{
  public static void main(String args[]){
    System.out.println(Machine.COFFEE_GRINDER.getCatalogId());
    System.out.println(Machine.COFFEE_MACHINE.isOfType(Machine.BASIC_MACHINE)); 
    //The above should be true.
  }

  private enum Machine {
    BASIC_MACHINE (-1),
    BEVERAGE (-1),
    COFFEE(-1),
    COFFEE_GRINDER (5),
    COFFEE_MACHINE (6),
    GARDEN (-1),
    LAWN_MOWER (28);

    private final int catalogId;

    public int getCatalogId(){
      return catalogId;
    }

    public boolean isOfType(Machine to){
      return this == to;
    }

    Machine (int catalogId) {
      this.catalogId = catalogId;
    }
  }
}

在上面的示例中,有一些机器,它们会出现在目录中并具有与之关联的 ID 号。还有部分和部分的部分。所以饮料机仍然是 BASIC_MACHINE。咖啡机仍然是饮料机。

程序中的一些功能在执行其功能之前必须检查机器是否实际上是 BEFERAGE 机器。目录中的 COFFEE_GRINDER 和 COFFEE_MACHINE 都将检出,并且该函数应该通过。

我正在寻找的行为类似于 instanceof 或抽象类的继承。无论如何,COFFEE_MACHINE 最终是 BASIC_MACHINE 的一种,我想检查一下。

所以:

Machine.COFFEE_MACHINE isa Machine.COFFEE
Machine.BEVERAGE isa MACHINE.BASIC_MACHINE
Machine.LAWN_MOWER isa Machine.GARDEN == Machine.BASIC_MACHINE
Machine.COFFEE_MACHINE isnota Machine.COFFEE_GRINDER
Machine.LAWN_MOWER isnota Machine.COFFEE

【问题讨论】:

  • 你只需要从最专业的enum值开始遍历继承路径,检查每一步。听起来很琐碎。
  • VENDING 未定义。你的意思是BEVERAGE?
  • 不能赋值Machine.COFFEE_MACHINE = Machine.COFFEE等,因为枚举常量是常量。 “实施什么?”如果你能描述你想要完成的“某事”,那将会有所帮助。标题提到了继承,但除了匿名主体类之外,您不能子类化枚举,并且您没有说明继承与任何事情有什么关系。您无需“检查类型”即可知道每个 是 对象的常量的类型为 Machine。如图所示,您的代码将无法编译。请说明你想要什么,并提供可编译的代码。
  • @LewBloch 我不认为 OP 试图在那里分配值。我把它读作 OP 表示继承的符号,即COFFEE_MACHINE“扩展”COFFEE,它扩展了BEVERAGE,它扩展了BASIC_MACHINE,在抽象意义上,而不是Java 类继承意义上。问题写得不好,我和你一样想,直到我重新阅读了这个问题。对我来说,似乎 OP 想要相当于 instanceof 来比较 Machine 枚举,例如COFFEE_MACHINE 是 BEVERAGE 的实例,但 LAWN_MOWER 不是 COFFEE 的实例。
  • 你们是对的。我含糊其辞。我希望这让它更清楚一点。我也有一个解决方案,但我不确定它是否有任何好处。

标签: java inheritance enums


【解决方案1】:

一种可能的解决方案是使用回调和保存的超类型来模拟某些继承。 我很好奇这是否是最好的方法。

实现如下:

//Test code of course.
public class Start{
  public static void main(String args[]){
    System.out.println(Machine.COFFEE_GRINDER.getCatalogId());
    System.out.println(Machine.COFFEE_MACHINE.isOfType(Machine.BASIC_MACHINE)); //Should be true.
  }

  private enum Machine {
    BASIC_MACHINE (-1),
    BEVERAGE (-1, BASIC_MACHINE),
    COFFEE(-1, BEVERAGE),
    COFFEE_GRINDER (5, COFFEE),
    COFFEE_MACHINE (6, COFFEE),
    GARDEN (-1, BASIC_MACHINE),
    LAWN_MOWER (28, GARDEN);

    private int catalogId;
    private Machine superMachine;

    public int getCatalogId(){
      return catalogId;
    }

    public Machine getSuperMachine(){
      return superMachine;
    }

    //With callback to superMachine (if present)
    public boolean isOfType(Machine to){
      return this == to || (getSuperMachine() != null && getSuperMachine().isOfType(to));
    }

    Machine (int catalogId) {
      this.catalogId = catalogId;
    }

    Machine (int catalogId, Machine superMachine) {
      this(catalogId);
      this.superMachine = superMachine;
    }
  }
}

【讨论】:

    【解决方案2】:

    如果我正确理解您的目标,您想表达enum 常量之间的关系网络。考虑到继承不一定与您希望表达的关系保持一致。继承对类型之间的is-a 关系建模;你想要实例之间的connects-to 关系。也许使用与“超级/继承”不同的术语,例如“所有者拥有”。您可以在每个常量中嵌入一个指向 owner 实例的指针,并在静态初始化程序和构造函数中创建一个无环有向图结构。

    public enum NetworkedMachine
    {
    BASIC_MACHINE(-1, null),
    BEVERAGE(-1, BASIC_MACHINE),
    COFFEE(-1, BASIC_MACHINE),
    COFFEE_GRINDER(5, COFFEE),
    COFFEE_MACHINE(6, COFFEE),
    GARDEN(-1, BASIC_MACHINE),
    LAWN_MOWER(28, GARDEN),
    ;
    
    static final Map<NetworkedMachine, Set<NetworkedMachine>> owners;
    static {
      Map<NetworkedMachine, Set<NetworkedMachine>> ownership = new HashMap<>();
      for (NetworkedMachine machine : values()) {
        ownership.put(machine, new HashSet<>());
      }
      for (NetworkedMachine machine : values()) {
        if (machine.owner != null) {
          ownership.get(machine.owner).add(machine);
        }
      }
      for (NetworkedMachine machine : values()) {
        Set<NetworkedMachine> owns = ownership.get(machine);
        ownership.put(machine, Collections.unmodifiableSet(owned));
      }
      owners = Collections.unmodifiableMap(ownership);
    }
    
    private final int catalogId;
    private final NetworkedMachine owner;
    
    NetworkedMachine(int catalogId, NetworkedMachine machine) {
      this.catalogId = catalogId;
      this.owner = machine;
    }
    
    public int getCatalogId() {
      return catalogId;
    }
    
    public NetworkedMachine getOwner() {
      return owner;
    }
    
    public Set<NetworkedMachine> getOwns() {
      return owners.get(this);
    }
    
    public boolean isOwned() {
      return owner != null;
    }
    
    }
    

    测试输出:

    BASIC_MACHINE id: -1, owner: [null], owns: [GARDEN, BEVERAGE, COFFEE]
    BEVERAGE id: -1, owner: [BASIC_MACHINE], owns: []
    COFFEE id: -1, owner: [BASIC_MACHINE], owns: [COFFEE_GRINDER, COFFEE_MACHINE]
    COFFEE_GRINDER id: 5, owner: [COFFEE], owns: []
    COFFEE_MACHINE id: 6, owner: [COFFEE], owns: []
    GARDEN id: -1, owner: [BASIC_MACHINE], owns: [LAWN_MOWER]
    LAWN_MOWER id: 28, owner: [GARDEN], owns: []
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-17
      • 2012-05-04
      • 1970-01-01
      • 2023-03-09
      • 2023-03-17
      • 1970-01-01
      相关资源
      最近更新 更多