【问题标题】:How to use an enum as one would use an interface?如何像使用接口一样使用枚举?
【发布时间】:2016-05-06 07:55:15
【问题描述】:

如何将 SomeEnum1 或 SomeEnum2 分配给实现 SomeInterface 的“枚举”?我不能直接指定接口,因为它是一个类而不是枚举。

我确定有一个指定的语法糖可以使这项工作发挥作用,但我无法弄清楚。

例子:

public class Main {
   public interface SomeInterface {
       public String doSomething();
   }

   public enum SomeEnum1 implements SomeInterface {
      something1;

      @Override
      public String doSomething() {
         return "SomeEnum1";
      }
   }

   public enum SomeEnum2 implements SomeInterface {
      something2;

      @Override
      public String doSomething() {
         return "SomeEnum2";
      }
   }

   public static void main(String[] args) {
      // Works but not polymorphic
      SomeEnum1 e1 = SomeEnum1.something1;
      System.out.println(e1.name() + " " + e1.doSomething());

      // Not an enum
      // SomeInterface e2 = SomeEnum1.something1;
      // System.out.println(e2.name() + " " + e2.doSomething());

      // Bounds mismatch
      // Enum<SomeInterface> e3 = SomeEnum1.something1;
      // System.out.println(e3.name() + " " + e3.doSomething());
   }
}

【问题讨论】:

  • 所以您想使用SomeInterface 作为enum?在这种情况下,您需要SomeInterface 来扩展Enum,这是不可能的。即使将SomeInterface 替换为SomeAbstractClass,仍然是不可能的,因为所有enums 都是从java.lang.Enum 扩展而来的,而且Java 不支持多重继承。
  • How can I assign SomeEnum1 or SomeEnum2 to an "enum" 你不能,枚举不能扩展

标签: java interface enums polymorphism


【解决方案1】:

如果将值传递给方法,则可以使用泛型将 SomeInterface 的类型限制为 2 个约束:

public static void main(String[] args) {
    print(SomeEnum1.something1);
}

public static <T extends Enum & SomeInterface> void print(T t) {
    System.out.println(t.name() + " " + t.doSomething());
}

【讨论】:

  • 这正是我想要的。我不知道你可以这样使用&amp;
【解决方案2】:

你不能。
在 Java 中,枚举类型只能具有为该枚举类型定义的值。

最接近你真正想要的东西:

SomeInterface e2 = SomeEnum1.something1;

编辑:为了能够使用name() 方法,您需要将其添加到界面中,如下所示:

public interface SomeInterface {
    public String doSomething();
    public String name();
}

由于该方法已在任何 Enum 上可用,因此您不必重新实现它。

您是否有特定的原因希望它成为一个枚举?在这里使用这种方法,您可以获得SomeInterface 中定义的所有功能。我无法想象你为什么需要一个枚举 -> 如果我的答案不符合你的需要,请详细说明。

【讨论】:

  • 原因是我想保持对.name() 的访问,而不必在界面中实现它。虽然即使我实现了它,当我@Override 时我也可以调用.name()
  • 只需将name() 添加到界面即可。请参阅我编辑的答案-> 应该这样做。
【解决方案3】:

您可以声明一个静态方法并为每个枚举值提供一个实现,而不是让枚举实现一个接口。

public enum Animal {

    DOG {
        public void makeNoise() { System.out.println("Bark bark!"); }
    },

    CAT {
        public void makeNoise() { System.out.println("Prrrrr!"); }
    };

    public abstract void makeNoise();

}

这样你就可以这样使用它了:

Animal animal = Animal.DOG;
animal.makeNoise(); // prints "Bark bark!";

animal = Animal.CAT;
animal.makeNoise(); // prints "Prrrrr!"

【讨论】:

    【解决方案4】:

    你可以简单地做:

    SomeInterface e2 = SomeEnum1.something1;
    

    问题在于e2 是一个接口,它可以被任何类实现,也包括没有name() 方法的类。因此,如果您想从SomeInterface-type 引用中访问该方法,则必须将其包含在接口中:

    interface SomeInterface {
        String name();
    }
    

    但是,请注意SomeInterface仍然不是枚举,所以你不能打开它,不能使用EnumSetEnumMap等。通常有更好的解决方案。

    【讨论】:

      猜你喜欢
      • 2016-05-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-17
      • 1970-01-01
      • 2019-06-03
      • 1970-01-01
      相关资源
      最近更新 更多