Java中的枚举继承? [英] Enumeration inheritance in Java?

查看:97
本文介绍了Java中的枚举继承?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在做天体物理研究。我写了一个包含Star,Band和Datfile类的包。我也有枚举类型的BandName。每个星星包含几个乐队,每个乐队包含几个数据文件。



我有几个星系的观测资料。对于每个这些,我创建一个StarDatabase类(一个星形的HashMap)和一个Main类。



我遇到的问题是带有枚举类型的BandName。到目前为止,我使用的所有数据都在I和V频段。现在我有J,H和K波段的数据。如果我简单地将J,H和K添加到BandName,我所有循环遍历BandName中的所有项目并执行某些操作现在已被破坏。



任何想法?



编辑:总结我的问题,我希望每个包都有自己的BandName枚举,它可以迭代。但是这不起作用,因为Star包中的方法期望StarBandName类型的对象,并且我提供的类型为IndividualPackage.BandName。

解决方案

您不能从另一个枚举继承枚举,尽管您可以让您的枚举实现一个界面。技术问题(所有枚举都隐含地扩展 java.lang.Enum ,因此它们不能扩展另一个类,只能实现其他接口)不是偶然的:


在大多数情况下,枚举的可扩展性证明是
是一个坏主意。令人困惑的是,扩展类型的元素是基本类型的
的实例,反之亦然。没有一个很好的方式来枚举基本类型及其扩展名的所有
元素。最后,可扩展性会使设计和实现的许多方面使
复杂化。


有效的Java第2版,项目34。



但是,我不完全明白你的问题:你没有使用 values()来迭代你的枚举?那么你不用担心用新的值扩展你的枚举。



请更清楚地说明破是什么意思。



更新:,所以您需要为不同类型的星星提供不同的乐队组 - 可以使用扩展常用界面的不同枚举来实现,例如:

  interface Band {
String getName();
void doStuff();
...
}

枚举BandsVI实现乐队{
V,I;
public String getName(){return toString(); }
public void doStuff(){/ *适用于这些乐队的东西* /}
...
}

枚举乐队JHK实现乐队{
J,H,K;
public String getName(){return toString(); }
public void doStuff(){/ *适合这些乐队的东西* /}
...
}

您可以通过使Star类成为通用的方式来使用这些:

 星级< T扩展枚举< T> &安培;带> {
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(); //打印V I
star2.printBandNames(); //打印J H K

如果乐队被组织成不同的组,这很好。然而,如果有混合乐队组的星星,您可能会喜欢另一种方法:

  class Star {
private名单< ;?延伸带> 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


I am doing astrophysical research. I wrote a package containing the classes Star, Band, and Datfile. I also have the enumerated type of BandName. Each star contains several Bands, each Band contains several Datfiles.

I have observational data for several galaxies. For each of these, I make a StarDatabase class (a HashMap of Stars) and a Main class.

The problem I'm having is with the enumerated type of BandName. So far, all of the data I have used has been in the I and V bands. Now I have data in J, H, and K bands. If I simply add J, H, and K to BandName, all of my loops that iterate over all of the items in BandName and do something are now broken.

Any ideas?

Edit: To sum up my problem, I want every package to have its own BandName enum that it can iterate through. But this doesn't work, because the methods in the Star package are expecting objects of type Star.BandName and I am providing objects of type IndividualPackage.BandName.

解决方案

You can't inherit an enum from another enum, although you can have your enum implement an interface. The technical problem (that all enums implicitly extend java.lang.Enum, thus they can't extend another class, only implement additional interfaces) is no accident:

For the most part, extensibility of enums turns out to be a bad idea. It is confusing that elements of an extension type are instances of the base type and not vice versa. There is no good way to enumerate over all of the elements of a base type and its extension. Finally, extensibility would complicate many aspects of the design and implementation.

From Effective Java 2nd Edition, Item 34.

However, I don't fully understand your problem: haven't you used values() for iterating through your enum? Then you shouldn't worry about extending your enum with new values.

Please specify more clearly what "broken" is supposed to mean.

Update: so you need to have distinct sets of bands for different types of stars - this can be implemented using distinct enums extending a common interface, e.g.:

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 */ }
  ...
}

And you can use these by making your Star class generic:

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

This works nicely if the bands are organized into distinct groups. If there are stars with mixed band groups, however, you might prefer an alternative approach:

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}));
...

This allows you to set up stars with an arbitrary mix of bands. However, this way you can't use EnumSet or EnumMap on the bands.

这篇关于Java中的枚举继承?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆