Java中的枚举继承?

发布于 2024-09-12 21:42:07 字数 466 浏览 5 评论 0原文

我正在做天体物理学研究。我编写了一个包含 Star、Band 和 Datfile 类的包。我还有BandName的枚举类型。每颗星包含多个 Band,每个 Band 包含多个 Datfile。

我有几个星系的观测数据。对于其中每一个,我创建一个 StarDatabase 类(星星的 HashMap)和一个 Main 类。

我遇到的问题是 BandName 的枚举类型。到目前为止,我使用的所有数据都在 I 和 V 波段。现在我有 J、H 和 K 波段的数据。如果我只是将 J、H 和 K 添加到 BandName,那么迭代 BandName 中所有项目并执行某些操作的所有循环现在都会被破坏。

有什么想法吗?

编辑:总结我的问题,我希望每个包都有自己可以迭代的 BandName 枚举。但这不起作用,因为 Star 包中的方法需要 Star.BandName 类型的对象,而我正在提供 individualPackage.BandName 类型的对象。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

墨小墨 2024-09-19 21:42:07

尽管您可以让您的枚举实现一个接口,但您不能从另一个枚举继承一个枚举。技术问题(所有枚举都隐式扩展 java.lang.Enum,因此它们不能扩展另一个类,只能实现附加接口)并非偶然:

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

来自 Effective Java 第二版,第 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}));
...

这允许您设置具有任意混合波段的恒星。但是,这样您就无法在 band 上使用 EnumSetEnumMap

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.

岁月蹉跎了容颜 2024-09-19 21:42:07

所有枚举都隐式扩展 java.lang.Enum。由于 Java 不支持多重继承,枚举不能扩展任何其他东西。 - http://download.oracle.com/javase/tutorial/java /javaOO/enum.html

All enums implicitly extend java.lang.Enum. Since Java does not support multiple inheritance an enum cannot extend anything else. - http://download.oracle.com/javase/tutorial/java/javaOO/enum.html

舂唻埖巳落 2024-09-19 21:42:07

这就是我要做的(伪代码):

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。每个启动都有它使用的带列表,因此它可以迭代所有带。

This is what I'd do (pseudo-code):

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

This way you can add bands by just creating more Band objects. Each start has the list of bands it uses so it can iterate over all them.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文