枚举可以有抽象方法吗?

发布于 2024-12-04 15:11:16 字数 44 浏览 3 评论 0原文

枚举可以有抽象方法吗?如果是这样,有什么用,并给出一个场景来说明这种用法。

Can an enum have abstract methods? If so, what is the use, and give a scenario which will illustrate this usage.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

不羁少年 2024-12-11 15:11:16

是的,但您可能更喜欢实现接口的枚举,看这里 。我认为它看起来好多了。这是抽象方法的示例:

public enum Animal {
    CAT {
        public String makeNoise() { return "MEOW!"; }
    },
    DOG {
        public String makeNoise() { return "WOOF!"; }
    };

    public abstract String makeNoise();
}

Yes, but you may prefer enum which implements an interface, Look here. I think It looks much better. This is example for abstract method:

public enum Animal {
    CAT {
        public String makeNoise() { return "MEOW!"; }
    },
    DOG {
        public String makeNoise() { return "WOOF!"; }
    };

    public abstract String makeNoise();
}
寄居者 2024-12-11 15:11:16

是的,您可以在enum声明中定义abstract方法当且仅当所有枚举值都具有带有这些方法的实现的自定义类体(即任何具体的枚举值都可能缺少实现)。

public enum Foo {
  BAR {
    public void frobnicate() {
      // do BAR stuff
    }
  },
  BAZ {
    public void frobnicate() {
      // do BAZ stuff
    }
  };

  public abstract void frobnicate();
}

Yes, you can define abstract methods in an enum declaration if and only if all enum values have custom class bodies with implementations of those methods (i.e. no concrete enum value may be lacking an implementation).

public enum Foo {
  BAR {
    public void frobnicate() {
      // do BAR stuff
    }
  },
  BAZ {
    public void frobnicate() {
      // do BAZ stuff
    }
  };

  public abstract void frobnicate();
}
倾其所爱 2024-12-11 15:11:16

就像 @lukastymo 的答案一样,可以在枚举中实现抽象方法,并且在枚举中添加方法时最好实现接口。

从 Java 8 及更高版本开始,您可以使用 lambda 来实现枚举中的方法,以实现更小的代码。通过公开运行给定 lambda 的公共方法,可以在枚举外部执行这些 lambda。

public enum ScheduleRepeat {
  DAILY(date -> date.plusDays(1)),
  WEEKLY(date -> date.plusWeeks(1)),
  MONTHLY(date -> date.plusMonths(1)),
  QUARTERLY(date -> date.plusMonths(3)),
  BIANNUALLY(date -> date.plusMonths(6)),
  ANNUALLY(date -> date.plusYears(1)),
  ;

  private final Function<LocalDate, LocalDate> nextDateFunction; // or UnaryOperator<LocalDate>

  ScheduleRepeat(Function<LocalDate, LocalDate> nextDateFunction) {
    this.nextDateFunction = nextDateFunction;
  }

  public LocalDate calculateNextDate(LocalDate dateFrom) {
    return nextDateFunction.apply(dateFrom);
  }
}

然后枚举可以这样使用:

LocalDate today = LocalDate.of(2019, 9, 18); // 2019 Sep 18
ScheduleRepeat.DAILY.calculateNextDate(today); // 2019-09-19
ScheduleRepeat.MONTHLY.calculateNextDate(today); // 2019-10-19

这并不完全是从枚举本身或接口实现抽象方法,但我认为这种使用 lambda 添加方法的方法看起来很干净。

Just like @lukastymo 's answer, it is possible to implement an abstract method in enum and it is preferred to implement an interface when adding a method in an enum.

From Java 8 and above, you can use lambda to implement methods in an enum for smaller code. These lambda can be executed outside the enum by exposing a public method that runs the given lambda.

public enum ScheduleRepeat {
  DAILY(date -> date.plusDays(1)),
  WEEKLY(date -> date.plusWeeks(1)),
  MONTHLY(date -> date.plusMonths(1)),
  QUARTERLY(date -> date.plusMonths(3)),
  BIANNUALLY(date -> date.plusMonths(6)),
  ANNUALLY(date -> date.plusYears(1)),
  ;

  private final Function<LocalDate, LocalDate> nextDateFunction; // or UnaryOperator<LocalDate>

  ScheduleRepeat(Function<LocalDate, LocalDate> nextDateFunction) {
    this.nextDateFunction = nextDateFunction;
  }

  public LocalDate calculateNextDate(LocalDate dateFrom) {
    return nextDateFunction.apply(dateFrom);
  }
}

Then the enum can be used like:

LocalDate today = LocalDate.of(2019, 9, 18); // 2019 Sep 18
ScheduleRepeat.DAILY.calculateNextDate(today); // 2019-09-19
ScheduleRepeat.MONTHLY.calculateNextDate(today); // 2019-10-19

This isn't exactly implementing an abstract method from the enum itself or from an interface, but I think this approach of adding method using lambda looks clean.

征棹 2024-12-11 15:11:16

是的,枚举可以包含抽象方法 - 如果您有自己的每个枚举常量的实现,则可以使用此方法。 (或者您可以省略使用抽象方法,并使用每个枚举常量的自定义值 具有自定义值的枚举Java

例如(特定于常量的方法实现

enum TrafficSignal {

    RED{
        @Override
        public void action(){
            System.out.println("STOP");
        }
    }, 
    GREEN{
        @Override
        public void action(){
            System.out.println("GO");
        }
    }, 
    ORANGE{
        @Override
        public void action(){
            System.out.println("SLOW DOWN");
        }
    };


    public abstract void action();
}

如果此方法对于所有枚举常量都是通用的,那么请考虑使用接口。 (Java 枚举隐式扩展了 java.lang.Enum 泛型类,因此您的枚举类型不能扩展另一个类(因为 java 不支持多重继承),但可以实现接口)

interface ColorInterface{
    void inLowerCase();
}

enum Color implements ColorInterface{

    RED, GREEN, ORANGE;

    @Override
    public void inLowerCase(){
        System.out.println(this.toString().toLowerCase());
    }
}

用法:

public class TestEnums{

     public static void main(String []args){
        TrafficSignal signal = TrafficSignal.RED;
        signal.action();

        ColorInterface color = Color.RED;
        color.inLowerCase();
     }
}

Out:

STOP
red

考虑策略枚举模式,但并非所有枚举常量都具有共同的行为。 [Effective Java - Joshua Bloch - 第三版。第166页]

Yes enum can contain abstract method - you can use this approach if you have own implementation per enum constants. (or you can omit using abstract method with using customized value per enum constant Enum with customized value in Java)

for example (constant-specific method implementations)

enum TrafficSignal {

    RED{
        @Override
        public void action(){
            System.out.println("STOP");
        }
    }, 
    GREEN{
        @Override
        public void action(){
            System.out.println("GO");
        }
    }, 
    ORANGE{
        @Override
        public void action(){
            System.out.println("SLOW DOWN");
        }
    };


    public abstract void action();
}

If this method is common for all enum constants then consider using interface. (Java enums extend the java.lang.Enum generic class implicitly, so your enum types cannot extend another class(becouse java does not support multiple inheritance) but can implement interface)

interface ColorInterface{
    void inLowerCase();
}

enum Color implements ColorInterface{

    RED, GREEN, ORANGE;

    @Override
    public void inLowerCase(){
        System.out.println(this.toString().toLowerCase());
    }
}

Usage:

public class TestEnums{

     public static void main(String []args){
        TrafficSignal signal = TrafficSignal.RED;
        signal.action();

        ColorInterface color = Color.RED;
        color.inLowerCase();
     }
}

Out:

STOP
red

Consider the strategy enum pattern if some, but not all, enum constants share common behaviors. [Effective Java - Joshua Bloch - third edition. page 166]

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文