Java:具有具体实现的抽象枚举

是否有一种方法可以基于枚举名称创建具有不同值的枚举抽象?

在这里我可以找到一些有用的类,例如抽象枚举:

public class StatusUpdater {
public foo(bool one,bool two,bool three,AbstractEnum status) {
    if (one) {
        caseone(status);
    }

    if (two) {
        caseTwo(status);
    }

    if (three) {
        caseThree(status);
    }
}

private void caseone(CaseoneEnum status) {
    status.getvalue(); //return case one value + case one implementation
}

private void caseTwo(CaseTwoEnum status) {
    status.getvalue(); //return case two value + case two implementation
}

private void caseThree(CaseThreeEnum status) {
    status.getvalue(); //return case three value + case three implementation
}

}

其中一个枚举的具体实现如下:

public enum CaseoneEnum {
STATUS_ONE("one"),STATUS_TWO("two");

private final String status;

CaseoneEnum(final String status) {
    this.status = status;
}

@Override
String getvalue(){return status;}

另一个实现将具有相同的枚举名称,但值不同:

public enum CaseTwoEnum {
STATUS_ONE("oneTwo"),STATUS_TWO("twoTwo");

private final String status;

CaseTwoEnum(final String status) {
    this.status = status;
}

@Override
String getvalue(){return status;}

调用main方法应如下所示:

updater.foo(true,true,false,AbstractEnum.STATUS_ONE);

有没有一种方法可以创建一些“抽象的”枚举,并将其传递给foo(),并在检查大小写后采用此枚举的具体实现。所有具体枚举的枚举名称将保持不变,但值将有所不同。我会想象这样的“抽象”枚举:

public enum AbstractEnum {
STATUS_ONE,STATUS_TWO;

@Override
String getvalue();

有没有办法以一种简洁的方式实现类似的目标?

zxllpyj 回答:Java:具有具体实现的抽象枚举

实际上所有枚举都是对象Enum的后代,这已经构成了泛型,您可以使用它来实现独立于实际枚举实现的方法签名。

您的代码然后显示出,对于每个“个案”,您都确切地知道期望哪个枚举,因此您可以在调用专用方法时简单地对输入对象进行类型转换

我接受了您的代码并对其进行了一些修改,以演示我的建议。

两个枚举实现

public enum CaseOneEnum {
    STATUS_ONE("one"),STATUS_TWO("two");

    private final String status;

    CaseOneEnum(final String status) {
        this.status = status;
    }

    String getValue() {
        return status;
    }
}

public enum CaseTwoEnum {
     STATUS_THREE("three"),STATUS_FOUR("four");

     private final String status;

     CaseTwoEnum(final String status) {
         this.status = status;
     }

     String getValue() {
         return status;
     }
 }

StatusUpdater类

public class StatusUpdater {

    public String foo(int caze,Enum<?> status) {

        if (caze == 1) {
            return caseOne((CaseOneEnum) status);
        }

        if (caze == 2) {
            return caseTwo((CaseTwoEnum) status);
        }
        return null;
    }

    private String caseOne(CaseOneEnum status) {
        return status.getValue();
    }

    private String caseTwo(CaseTwoEnum status) {
        return status.getValue();
    }
}

最要注意的是,在调用每种case方法时,foo方法签名公开了 Enum 类型的参数和 class cast 类型的参数。

最后是一个JUnit演示。

public class StatusUpdaterTest {

    @Test
    public void testStatusUpdaterCase1() {
        StatusUpdater updater = new StatusUpdater();
        assertEquals(CaseOneEnum.STATUS_ONE.getValue(),updater.foo(1,CaseOneEnum.STATUS_ONE));
}

    @Test
    public void testStatusUpdaterCase2() {
        StatusUpdater updater = new StatusUpdater();
        assertEquals(CaseOneEnum.STATUS_TWO.getValue(),CaseOneEnum.STATUS_TWO));
    }

    @Test
    public void testStatusUpdaterCase3() {
        StatusUpdater updater = new StatusUpdater();
        assertEquals(CaseTwoEnum.STATUS_THREE.getValue(),updater.foo(2,CaseTwoEnum.STATUS_THREE));
    }

    @Test
    public void testStatusUpdaterCase4() {
        StatusUpdater updater = new StatusUpdater();
        assertEquals(CaseTwoEnum.STATUS_FOUR.getValue(),CaseTwoEnum.STATUS_FOUR));
    }
}

希望这会有所帮助!

欢呼

,

这是使用界面的解决方案。因为枚举可以实现接口,所以您可以摆脱重载的方法(除非它们的实现不同)。

interface MyEnumInterface {
    String getValue();
}

这样,您的StatusUpdater类将变为:

public class StatusUpdater {
    public void foo(MyEnumInterface status) {
        anyCase(status);
    }

    //You can duplicate this with caseOne,caseTwo methods if
    //implementations are actually different
    private void anyCase(MyEnumInterface status) {
        status.getValue(); 
    }
}

然后您以这种方式调用foo方法:

updater.foo(1,CaseOneEnum.STATUS_ONE);
updater.foo(1,CaseTwoEnum.STATUS_ONE);

然后剩下的就是让您的枚举实现接口(它们已经具有方法):

enum CaseOneEnum implements MyEnumInterface {
    STATUS_ONE("one"),STATUS_TWO("two");

    private final String status;

    CaseOneEnum(final String status) {
        this.status = status;
    }

    @Override
    public String getValue() {
        return status;
    }
}

//other enums implement the
,

您正在混淆定义常量和相关数据的枚举。您要定义“抽象枚举”的原因是,只有一组常数,因此实际结论是应该只有一个enum

尽管enum类型允许直接保存关联数据,但是您应该仅将此功能用于规范关联。当像您的情况那样,存在不同组的关联数据时,您不应将它们存储为enum类型,因为这仅允许一对一的关系。此外,与其创建定义相同常数的另一个冗余enum类型,不如将数据存储在EnumMap中,后者专门用于将数据与enum常数相关联。

将简单的enum类型定义为

public enum YourActualEnum {
    STATUS_ONE,STATUS_TWO
}

和具有不同关联数据的类,具体取决于用例:

public class StatusUpdater {
    private static final EnumMap<YourActualEnum,String> CASE1,CASE2,CASE3;
    static {
        CASE1 = new EnumMap<>(YourActualEnum.class);
        CASE1.put(YourActualEnum.STATUS_ONE,"one");
        CASE1.put(YourActualEnum.STATUS_TWO,"two");
        CASE2 = new EnumMap<>(YourActualEnum.class);
        CASE2.put(YourActualEnum.STATUS_ONE,"oneTwo");
        CASE2.put(YourActualEnum.STATUS_TWO,"twoTwo");
        CASE3 = new EnumMap<>(YourActualEnum.class);
        CASE3.put(YourActualEnum.STATUS_ONE,"oneThree");
        CASE3.put(YourActualEnum.STATUS_TWO,"twoThree");
    }
    public void foo(boolean one,boolean two,boolean three,YourActualEnum status) {
        if (one) {
            caseOne(status,CASE1);
        }

        if (two) {
            caseTwo(status,CASE2);
        }

        if (three) {
            caseThree(status,CASE3);
        }
    }

    private void caseOne(YourActualEnum status,EnumMap<YourActualEnum,String> m) {
        m.get(status);
    }

    private void caseTwo(YourActualEnum status,String> m) {
        m.get(status);
    }

    private void caseThree(YourActualEnum status,String> m) {
        m.get(status);
    }
}
本文链接:https://www.f2er.com/3160946.html

大家都在问