[英]Java: Abstract enum with concrete implementations
有沒有辦法根據枚舉名稱創建具有不同值的枚舉抽象?
這是一個 class ,我會發現類似抽象枚舉的東西很有用:
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();
有沒有辦法以一種簡潔的方式實現類似的目標?
實際上,所有枚舉都是 object 枚舉的后代,這已經構成了一個泛型類型,您可以使用它來實現獨立於實際枚舉實現的方法簽名。
然后,您的代碼顯示,對於每個“案例”,您確切地知道期望哪個枚舉,因此您可以在調用專用方法時簡單地class 轉換輸入 object 。
我拿走了您的代碼並對其進行了一些修改以演示我的建議。
兩個枚舉實現
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 class
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();
}
}
需要注意的最重要的事情是 foo 方法簽名公開了Enum類型的參數,以及在調用每個 case 方法時的class 強制轉換。
最后用 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(), updater.foo(1, 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(), updater.foo(2, CaseTwoEnum.STATUS_FOUR));
}
}
希望這可以幫助!
干杯
這是使用接口的解決方案。 因為枚舉可以實現接口,所以您可以擺脫重載的方法(除非它們的實現不同)。
interface MyEnumInterface {
String getValue();
}
這樣,您的 StatusUpdater class 變為:
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
中,該 EnumMap 專門用於將數據與enum
常量相關聯。
定義一個簡單的enum
類型為
public enum YourActualEnum {
STATUS_ONE,
STATUS_TWO
}
以及具有不同關聯數據的 class ,具體取決於用例:
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, EnumMap<YourActualEnum,String> m) {
m.get(status);
}
private void caseThree(YourActualEnum status, EnumMap<YourActualEnum,String> m) {
m.get(status);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.