【问题标题】:Return calculated value from enum从枚举返回计算值
【发布时间】:2013-04-19 12:35:27
【问题描述】:

请问我的问题是两个,非常简单

  1. 按原样误解枚举

  2. 这个想法在我的代码中遗漏了一些重要的抽象

代码示例,其中oprt.calc(x, y) 不可编译,带有警告cannot find symbol

public enum Operation {

    PLUS {
        public double calc(double x, double y) {
            return x + y;
        }
    },
    MINUS {
        public double calc(double x, double y) {
            return x - y;
        }
    },
    MULTILPLE {
        public double calc(double x, double y) {
            return x * y;
        }
    },
    DIVIDED_BY {
        public double calc(double x, double y) {
            return x / y;
        }
    };

    public static void main(String args[]) {
        double x = 15.25;
        double y = 24.50;
        for (Operation oprt : Operation.values()) {
            System.out.println(x + " " + oprt + " " 
                    + y + " = " + oprt.calc(x, y));
        }
    }
}

【问题讨论】:

  • 附带说明,这听起来像是 Lambda 表达式的完美应用,Java 8 的一个即将推出的功能。docs.oracle.com/javase/tutorial/java/javaOO/…
  • 将其加载到 Eclipse 时收到的错误消息是 The method calc(double, double) is undefined for the type Operation,它指向下面其他人提供的解决方案。
  • +1 我不知道枚举有这样的东西。
  • @JJPA,它们也可以有实例变量和构造函数。 docs.oracle.com/javase/tutorial/java/javaOO/enum.html
  • @ColinD 感谢您的链接

标签: java enums


【解决方案1】:

你错过的是 calc() 方法的抽象声明:

enum Operation {

  PLUS {
      public double calc(double x, double y) {
          return x + y;
      }
  },
  MINUS {
      public double calc(double x, double y) {
          return x - y;
      }
  },
  MULTILPLE {
      public double calc(double x, double y) {
          return x * y;
      }
  },
  DIVIDED_BY {
      public double calc(double x, double y) {
          return x / y;
      }
  };

  **public abstract double calc(double x, double y);**

  public static void main(String args[]) {
      double x = 15.25;
      double y = 24.50;
      for (Operation oprt : Operation.values()) {
          System.out.println(x + " " + oprt + " " 
                  + y + " = " + oprt.calc(x, y));
      }
  }
}

【讨论】:

    【解决方案2】:

    你需要在枚举中直接声明一个抽象方法double calc(double x, double y),并在每个枚举成员中覆盖它。

    【讨论】:

    • 能否请您澄清您的回答中的第二部分,and override it in every enum member,与@Adam Dyga 的回答相比,是否有更安全的、额外的或......
    • 没有。亚当的密码就是我的意思。我喜欢在覆盖另一个方法的方法上添加 @Override 注释,如果基方法被重命名、删除或更改其签名,编译器会出错,但在这种特殊情况下,它并不是真正有用,除了文档目的。
    • :-) 抱歉,我没有明确注释,您是正确的 IDE 通知
    【解决方案3】:

    使用枚举方法的正确语法是:

    private enum Operation {
        PLUS, MINUS, MULTILPLE, DIVIDED_BY;
    
        public double calc(double x, double y) {
            switch (this) {
            case PLUS:
                return x + y;
            case MINUS:
                return x - y;
            case MULTILPLE:
                return x * y;
            case DIVIDED_BY:
                return x / y;
            }
            return 0;
        }
    }
    
    public static void main(String args[]) throws IOException {
    
        double x = 15.25;
        double y = 24.50;
        for (Operation oprt : Operation.values()) {
            System.out.println(x + " " + oprt + " " + y + " = "
                    + oprt.calc(x, y));
        }
    
    }
    

    【讨论】:

    • Java 枚举可以有抽象方法,可以为每个特定的枚举值实现;我认为在大多数情况下,这比使用开关的解决方案更可取
    • 您能解释一下为什么需要存在抽象方法吗?这个枚举设计决策的“语义”是什么?
    【解决方案4】:

    您正在覆盖 calc(),而您没有原始的 calc() 方法。要么声明一个抽象方法:

    public abstract double calc(double x, double y);
    

    或声明一个具有默认实现的具体方法:

    public double calc(double x, double y)
    {
        // ...
    }
    

    【讨论】:

      【解决方案5】:

      它无法编译,因为目前,calc 方法仅存在于您的enum 的每个可能值中 - 但它不存在于类型 Operation 本身。这就是为什么你的编译器(和我的)不接受它。

      所以,你需要在type中定义方法。也许是这样的:

      public abstract double calc(double x, double y);
      

      您的枚举值(PLUS、MINUS、MULTIPLE 和 DIVIDED_BY 都实现了该方法。

      【讨论】:

        【解决方案6】:
        public double calc(double x, double y){}
        

        和

        一样
        private double calc(double x,double y){}
        

        除非您将 calc() 方法添加到枚举 Operation。根据 JLS:

        Instance methods declared in these class bodies are may be invoked outside 
        the enclosing enum type only if they override accessible methods in 
        the enclosing enum type.
        

        所以基本上,oprt 的类型是Operation,并且由于Operation 没有任何名为double calc(double x,double y) 的方法声明,因此您不能使用oprt 调用该方法。简而言之,类主体中定义的方法应该是被覆盖的方法,以便它们可以被外部访问。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多