Java中的枚举继承?
Posted
技术标签:
【中文标题】Java中的枚举继承?【英文标题】:Enumeration inheritance in Java? 【发布时间】:2010-08-06 21:31:56 【问题描述】:我正在做天体物理学研究。我编写了一个包含 Star、Band 和 Datfile 类的包。我也有 BandName 的枚举类型。每颗星包含几个波段,每个波段包含几个数据文件。
我有几个星系的观测数据。对于其中的每一个,我创建了一个 StarDatabase 类(一个星的 HashMap)和一个 Main 类。
我遇到的问题是 BandName 的枚举类型。到目前为止,我使用的所有数据都在 I 和 V 波段。现在我有 J、H 和 K 波段的数据。如果我只是将 J、H 和 K 添加到 BandName,那么我所有遍历 BandName 中所有项目并执行某些操作的循环现在都会中断。
有什么想法吗?
编辑:总结一下我的问题,我希望每个包都有自己的 BandName 枚举,它可以迭代。但这不起作用,因为 Star 包中的方法需要 Star.BandName 类型的对象,而我提供的是 IndividualPackage.BandName 类型的对象。
【问题讨论】:
你为什么要遍历 BandNames? 如果确实需要添加新的乐队,我使用乐队名的任何地方都不需要更新。 包对应什么?也就是说,您为什么首先要对这些类进行子类化? 我有几个包,每个星系一个,都需要用到Star、Band和Datfile。它们都有不同的 StarDatabase(因为它们所有的数据都由其他人以不同的方式组织)和 Main 类,其中两个有 GUI。 add values to enum的可能重复 【参考方案1】:你不能从另一个枚举继承一个枚举,尽管你可以让你的枚举实现一个接口。技术问题(所有枚举都隐式扩展java.lang.Enum
,因此它们不能扩展另一个类,只能实现附加接口)并非偶然:
在大多数情况下,枚举的可扩展性结果是 是个坏主意。扩展类型的元素是 基本类型,反之亦然。没有很好的方法来枚举所有 基本类型的元素及其扩展。最后,可扩展性会变得复杂 设计和实现的许多方面。
来自Effective Java 2nd Edition,第 34 条。
但是,我不完全理解您的问题:您没有使用values()
来遍历您的枚举吗?那么你不应该担心用新值扩展你的枚举。
请更清楚地说明“破碎”的含义。
更新:因此您需要为不同类型的星星设置不同的波段 - 这可以使用扩展通用接口的不同枚举来实现,例如:
interface Band
String getName();
void doStuff();
...
enum BandsVI implements Band
V, I;
public String getName() return toString();
public void doStuff() /* do stuff as appropriate for these bands */
...
enum BandsJHK implements Band
J, H, K;
public String getName() return toString();
public void doStuff() /* do stuff as appropriate for these bands */
...
您可以通过使您的 Star 类通用化来使用这些:
class Star<T extends Enum<T> & Band>
private Class<T> bandType;
public Star(Class<T> bandType) this.bandType = bandType;
public void printBandNames()
for (Band b : bandType.getEnumConstants())
System.out.println(b.getName());
public void doStuffOnAllBands()
for (Band b : bandType.getEnumConstants())
b.doStuff();
...
Star<BandsVI> star1 = new Star<BandsVI>(BandsVI.class);
Star<BandsJHK> star2 = new Star<BandsJHK>(BandsJHK.class);
star1.printBandNames(); // prints V I
star2.printBandNames(); // prints J H K
如果将乐队组织成不同的组,这会很好地工作。但是,如果有混合乐队的明星,您可能更喜欢另一种方法:
class Star
private List<? extends Band> bandTypes;
public Star(List<? extends Band> bandTypes) this.bandTypes = bandTypes;
public void printBandNames()
for (Band b : bandTypes)
System.out.println(b.getName());
...
...
Star star1 = new Star(Arrays.asList(BandsVI.values()));
Star star3 = new Star(Arrays.asList(new Band[]BandsVI.V, BandsVI.I, BandsJHK.K));
...
这使您可以使用任意组合的波段来设置星星。但是,这样您就不能在频段上使用EnumSet
或EnumMap
。
【讨论】:
例如,每个 Star 对象都会遍历 BandName.values() 并添加一个具有命名值的新 Band。然后那个 Band 在目录 /value 中查找以获取 datfiles。然后 GUI 从 BandName.values() 中的每个 Band 中创建一个新的 BandRadioButton... 以此类推。 @Earl,我仍然不明白问题出在哪里:新频段的 datfile 是否丢失,或者 GUI 是否混乱,或者...? GUI 确实搞砸了。与 V 和 I 波段有关的恒星根本不应该与 J、H 或 K 相互作用。我希望它遍历这些值(而不是显式命名它们),以防需要添加新的乐队 确实。 @Earl,我明白了。所以你有只有 V 和 I 波段的明星。其余的呢?他们只关注 J、H 和 K 波段,还是关注所有波段?【参考方案2】:所有枚举都隐式扩展 java.lang.Enum。由于 Java 不支持多重继承,因此枚举不能扩展其他任何东西。 - http://download.oracle.com/javase/tutorial/java/javaOO/enum.html
【讨论】:
我知道这一点。因此问题。 @Earl,他无法知道你知道这一点。如果您没有就该问题向我们提供足够的信息,我们很难或不可能给您提供好的答案。 我很抱歉。这听起来并不粗鲁。【参考方案3】:这就是我要做的(伪代码):
class Band
String name;
;
static Band J("J");
static Band K("K");
static ArrayList<Band> JK;
static ArrayList<Band> IHL;
class Star
Star(ArrayList<Band> bands)
这样您就可以通过创建更多的 Band 对象来添加 Band。每个起点都有它使用的波段列表,因此它可以遍历所有波段。
【讨论】:
以上是关于Java中的枚举继承?的主要内容,如果未能解决你的问题,请参考以下文章