如您所知,有些人用1个Enum实例声明单例,因为JVM保证将始终存在单个实例,并且没有并发问题要处理...

因此,具有多个实例的枚举又如何呢?
我们可以说枚举是共享公共接口的一种有序单例集吗?
为什么?

public enum EnumPriceType {

    WITH_TAXES {
        @Override
        public float getPrice(float input) {
            return input*1.20f;
        }
        public String getFormattedPrice(float input) {
            return input*1.20f + " €";
        }
        },

    WITHOUT_TAXES {
        @Override
        public float getPrice(float input) {
            return input;
        }
    },
    ;

    public abstract float getPrice(float input);

    public static void main(String[] args) {
        WITH_TAXES.getFormattedPrice(33f);
    }

}

在这段代码中为什么这样不起作用:
WITH_TAXES.getFormattedPrice(33f);
如果不通过公共接口就不能调用公共方法,那么声明公共方法有什么用呢?
我猜这就是为什么我看不到任何语法能够仅为枚举实例之一声明接口的原因。

编辑:

枚举实例似乎是一种特殊的匿名类。
因此,我理解为什么您不能调用该方法。

我的问题与以下内容有关:为什么匿名类不能实现接口(除了它可能已经实现的接口之外)!

我完全理解为什么我们不能这样做:
Vehicle veh = new Vehicle() {
    public String getName() {
        return "toto";
    }
};
veh.getName();

(这里的getName不是替代)

我不明白的原因是为什么我们不能使用匿名类来做到这一点:
Runnable veh = new Vehicle() implements Runnable {
    @Override
    public void run() {
        System.out.println("i run!");
    }
};
veh.run();

否则会导致相同的结果。
考虑一下:如果您不使用匿名类,则可以绝对扩展Vehicle类,然后使该子类实现您想要的任何其他接口...

我非常确定,如果可能的话,我们将能够以类型安全的方式调用WITH_TAXES.getFormattedPrice(33f),因为WITH_TAXES不是真正的EnumPriceType,而是一个EnumPriceType的子类,具有自己的接口,并且通过使用带有硬编码的WITH_TAXES的WITH_TAXES.getFormattedPrice(33f)进行调用,您可以在编译时知道正在调用的EnumPriceType子级。

所以我的问题是:有什么原因不能做到这一点?还是还没有完成?

最佳答案

您的枚举等效于以下普通类(实际上,这几乎是编译器将其转换为的类):

public abstract class EnumPriceType {

    public static final EnumPriceType WITH_TAXES = new EnumPriceType() {
        //getPrice() {...}
        //getFormattedPrice() {...}
    };

    public static final EnumPriceType WITHOUT_TAXES = new EnumPriceType() {
        //getPrice() {...}
    };

    public abstract float getPrice(float input);

    public static void main(String[] args) {
        WITH_TAXES.getFormattedPrice(33f);
    }
}
getFormattedPrice()方法在抽象类型上不可用,因此不能从main方法中调用。考虑如果将main方法重写为使用局部变量会发生什么:
public static void main(String[] args) {
    EnumPriceType foo = EnumPriceType.WITH_TAXES;
    foo.getFormattedPrice(33f);
}

由于getFormattedPrice()在基类上不可用,因此无法编译。由于WITH_TAXES实例是EnumPriceType的匿名子类,因此无法将本地变量定义为getFormattedPrice()方法可见的类型。

作为元数据观察,这是强类型语言(例如Java)和“鸭子类型”语言(例如Ruby)之间的主要区别。不管getFormattedPrice()变量中保存了哪种类型的对象,Ruby都会很乐意调用foo方法。

作为另一个元数据观察,对于同一个enum的不同常量,使用不同的set方法没有多大意义。如果不能将所需的所有内容作为抽象(或具体)方法放在基本枚举类型上,则可能是使用了错误的工具来解决问题。

07-28 08:16