[英]Using generic types with a Map typed with Enum keys in a subclass context
我有以下結構,父 class,幾個子類,每個子類都有自己的 Enum 和各種鍵。 父 class 需要有一個 map 具有以 Enum 為特征的鍵,但 Enum 類型是抽象的 - 它由正在實例化的子類確定。
我想使用泛型類型來要求 Enum 類型來自特定的 class - 因此您只能將 APPLE 添加到 Fruits 並將 CELERY 添加到 Veggies ,反之亦然。 我的應用程序還要求任何 Food object 能夠查詢其可能的類型(例如,打印出所有可能的類型,而不僅僅是我們在地圖中的類型)。
我怎樣才能使用泛型類型來使這一切正常工作? 我在 EnumSet 聲明Uncompilable source code - type argument E is not within bounds of type-variable E
。
import java.util.*;
public class sandbox {
private static class Food<E extends Enum> {
public Map<E, Integer> qty = new HashMap<>();
public EnumSet<E> types = EnumSet.allOf(E);
}
private static class Fruit extends Food<Fruit.Type> {
public static enum Type {
APPLE,
ORANGE
}
}
private static class Veggie extends Food<Veggie.Type> {
public static enum Type {
CUCUMBER,
CELERY
}
}
public static void main(String[] args) throws Exception {
Fruit mondays = new Fruit();
mondays.qty.put(Fruit.Type.APPLE, 1);
mondays.qty.put(Fruit.Type.ORANGE, 3);
Veggie tuesdays = new Veggie();
tuesdays.qty.put(Veggie.Type.CELERY, 10);
mondays.qty.forEach((f, qty) -> System.out.println("Buying " + f + " in qty " + qty));
tuesdays.qty.forEach((f, qty) -> System.out.println("Buying " + f + " in qty " + qty));
mondays.types.forEach(System.out::print);
}
}
我會利用枚舉可以實現接口這一事實,使用接口作為Food
的類型約束而不是Enum<>
。 然后將Food
抽象化,以便每個特定的食物子類型都可以聲明其枚舉類型。
private static interface FoodType {}
private static abstract class Food<T extends FoodType> {
public Map<T, Integer> qty = new HashMap<>();
protected abstract Set<T> getTypes();
}
private static class Fruit extends Food<Fruit.Type> {
public static enum Type implements FoodType {
APPLE,
ORANGE
}
@Override
protected Set<Type> getTypes() {
return EnumSet.allOf(Type.class);
}
}
private static class Veggie extends Food<Veggie.Type> {
public static enum Type implements FoodType {
CUCUMBER,
CELERY
}
@Override
protected Set<Type> getTypes() {
return EnumSet.allOf(Type.class);
}
}
如果您想要稍微DRY並避免在每個具體的Food
子類中實現getTypes()
,您可以在受保護的構造函數中傳入枚舉值數組。 像這樣:
private static interface FoodType { }
private static abstract class Food<T extends FoodType> {
public Map<T, Integer> qty;
public Set<T> types;
protected Food(T[] types) {
this.types = Set.of(types);
this.qty = new HashMap<>();
}
}
private static class Fruit extends Food<Fruit.Type> {
protected Fruit() {
super(Type.values());
}
public static enum Type implements FoodType {
APPLE,
ORANGE;
}
}
private static class Veggie extends Food<Veggie.Type> {
protected Veggie() {
super(Type.values());
}
public static enum Type implements FoodType {
CUCUMBER,
CELERY
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.