需要扩展类的枚举

发布于 2024-10-13 08:28:04 字数 314 浏览 2 评论 0 原文

我想要扩展我的抽象类 A 的类来提供枚举类型。我不需要约束类型本身,我只是想确保它们提供一些枚举类型。例如,我有一个抽象类 Animal,我想确保每个 Animal 都有一组行为。我不需要以任何方式限制这些行为或创建一个主列表;我只是想确保所有动物都返回象征性行为列表。

理想情况下,我想说:

public abstract class Animal {
  public List<Enum> getBehaviors(); 
}

但这不会干净地编译。

有什么想法吗?通过泛型来解决这个问题会更好吗?

I would like to require classes that extend my abstract class A to provide an enumerated type. I don't need to constrain the type itself, I just want to ensure that they provide some enumerated type. For example, I have an abstract class Animal and I want to ensure that every Animal has a set of behaviors. I don't need to constrain these behaviors or create a master list in any way; I just want to ensure that all Animals return a list of symbolic behaviors.

Ideally, I would like to say:

public abstract class Animal {
  public List<Enum> getBehaviors(); 
}

but this won't compile cleanly.

Any ideas? Would it be better to approach this via Generics?

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

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

发布评论

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

评论(4

别挽留 2024-10-20 08:28:04

好的,我将在这里扩展我的评论。

如果您想让 getBehaviors() 方法返回特定动物的行为列表,请使方法签名声明 List>返回对您没有任何帮助。从该方法获取 List> 的客户端无法用它做任何有用的事情(谁知道它是什么?)。该限制也没有做任何事情来帮助确保行为列表包含的对象类型实际上是“行为”,无论这在应用程序的上下文中意味着什么。它们可以是一周中的几天、一年中的几个月或任何东西!

我猜测你有一些像 DogBehavior 这样的 enum (带有像 BARKBITE 这样的常量,等),并且您希望确保列表中只允许此类行为。这些行为被收集在 enum 中的事实是一个实现细节。您应该做的是引入一个通用接口,将某些东西指定为行为。如果没有任何与行为关联的特定方法,它可能只是一个标记接口(不定义任何方法)。否则,您可能希望它有一些方法,例如:

public interface Behavior {
  public String getName();
  public void doBehavior();
  // etc.
}

然后,您可以有一些实现此接口的enum

public enum DogBehavior implements Behavior {
  BARK("Bark") {
    public void doBehavior() {
      // bark
    }
  },
  // etc.

  private final String name;

  DogBehavior(String name) {
    this.name = name;
  }

  public String getName() {
    return name;
  }
}

然后,“动物”可能看起来像:

public abstract class Animal {
  public abstract List<Behavior> getBehaviors(); 
}

这对我来说更有意义。

Ok, I'm going to expand my comment a bit here.

If you want to have your getBehaviors() method return a list of behaviors for a particular animal, making the method signature declare that a List<Enum<?>> is returned does nothing to help you. A client who gets your List<Enum<?>> from that method isn't able to do anything useful with it (who knows what it is?). The restriction also doesn't do anything to help ensure that the type of objects the behaviors list contains are actually "behaviors", whatever that means to in the context of your application. They could be days of the week, months of the year or just about anything!

What I'm guessing is that you have some enums like DogBehavior (with constants like BARK, BITE, etc.) and you want to ensure that only such behaviors are allowed in the list. The fact that these behaviors are collected in enums is an implementation detail. What you should do is introduce a common interface that designates something as a Behavior. If there aren't any specific methods associated with a Behavior, it could just be a marker interface (that defines no methods). Otherwise, you might want it to have some methods, like such:

public interface Behavior {
  public String getName();
  public void doBehavior();
  // etc.
}

You could then have some enums that implement this interface:

public enum DogBehavior implements Behavior {
  BARK("Bark") {
    public void doBehavior() {
      // bark
    }
  },
  // etc.

  private final String name;

  DogBehavior(String name) {
    this.name = name;
  }

  public String getName() {
    return name;
  }
}

Then, 'Animal' might look like:

public abstract class Animal {
  public abstract List<Behavior> getBehaviors(); 
}

Which makes a lot more sense to me.

丢了幸福的猪 2024-10-20 08:28:04

我有点困惑 - 如果您想要求所有 Animal 导出一组行为,那么理想情况下您的目标是能够编写如下内容:

Animal a = /* .. create some subtype of Animal .. */
List</* ?? */> behaviors = a.getBehaviors();

这里的问题是,如果如果您希望每个 Animal 为行为创建自己的枚举类型,则没有统一的方式来讨论这些行为,除非您显式指定代表它们的某种类型。也就是说,你不能填写/* ?? */ 除非在 Animal 接口中,您提供了所有 Animal 行为都应与之相关的类型。

一种选择是定义一个像这样的类:

public final class Behavior {
    private final String name;

    public Behavior(String name) {
        this.name = name;
    }
    public String getBehaviorName() {
        return name;
    }
    /* ... etc. ... */
}

然后,您可以为每个 Animal 类型定义 getBehaviors() ,以便它返回一个 Behavior< /代码> 对象。这为您提供了一个用于讨论行为的类型安全框架,并且可能能够为每个行为添加更复杂的操作。

I'm a bit confused - if you want to require all Animals to export a set of behaviors, then ideally your goal would be to be able to write something like this:

Animal a = /* .. create some subtype of Animal .. */
List</* ?? */> behaviors = a.getBehaviors();

The problem here is that if you want each Animal create its own enumerated type for behaviors, you have no unified way of talking about those behaviors unless you explicitly specify some type that represents them. In other words, you can't fill in the /* ?? */ above unless in the Animal interface you provide a type that all Animal behaviors should be related to.

One option would be to define a class like this one:

public final class Behavior {
    private final String name;

    public Behavior(String name) {
        this.name = name;
    }
    public String getBehaviorName() {
        return name;
    }
    /* ... etc. ... */
}

Then, you could have each Animal type define getBehaviors() so that it returns a list of Behavior objects. This gives you a type-safe framework for discussing behaviors, and potentially the ability to add more complex actions for each behavior.

清旖 2024-10-20 08:28:04

我认为有两件事是错误的。

首先,您需要将该方法标记为抽象。您没有提供实现。

其次,如果您不想收到警告,则应该对枚举进行参数化。如果您不需要进一步限制 Enum,则 Enum 应该足够了。

然而,正如其他人所指出的,这可能不是您想要的。 “行为”的枚举对你来说毫无用处。一旦从 getBehaviors() 返回,它们就没有任何功能。您可以迭代它们并列出它们,但这只不过是 List 的价值。

我认为您需要一个 List 其中Behavior 是一个为您做某事的接口。

编辑:上面的 ColinD 在同一点上击败了我。

2 things I see wrong.

First, you need to mark that method abstract. You didn't provide an implementation.

Second, the Enum should be parameterized if you don't want a warning. Enum<?> should be enough if you don't need to restrict the Enum further.

However, as others have noted, this probably is NOT what you want. An Enum of "behaviors" is useless to you. They have no functionality once returned from getBehaviors(). You could iterate through them and list them, but that's worth nothing more than a List<String>.

I would think that you want a List<Behavior> where Behavior is an interface that DOES something for you.

EDIT: ColinD above beat me to the punch on the same point.

行至春深 2024-10-20 08:28:04
public abstract class Animal {
  public List<? extends Enum<?>> getBehaviors(); 
}
public abstract class Animal {
  public List<? extends Enum<?>> getBehaviors(); 
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文