我想要求扩展我的抽象类A的类来提供枚举类型。我不需要约束类型本身,我只是想确保它们提供一些枚举类型。例如,我有一个抽象类Animal,我想确保每个Animal都有一组行为。我不需要约束这些行为或以任何方式创建主列表;我只想确保所有动物都返回一系列符号行为。
理想情况下,我想说:
public abstract class Animal {
public List<Enum> getBehaviors();
}
但这不会干净地编译。
有什么想法吗?通过Generics来解决这个问题会更好吗?
答案 0 :(得分:2)
我有点困惑 - 如果你想要求所有Animal
s导出一组行为,那么理想情况下你的目标是能够写出这样的东西:
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
个对象的列表。这为您提供了一个用于讨论行为的类型安全框架,并且可能为每个行为添加更复杂的操作。
答案 1 :(得分:2)
好的,我将在这里稍微扩展我的评论。
如果您希望让getBehaviors()
方法返回特定动物的行为列表,请使方法签名声明返回List<Enum<?>>
nothing 以帮助您。从该方法获取List<Enum<?>>
的客户端无法对其执行任何有用的操作(谁知道它是什么?)。限制也没有做任何事情来帮助确保行为列表包含的对象类型实际上是“行为”,无论在应用程序的上下文中意味着什么。它们可能是一周中的几天,一年中的几个月或几乎任何东西!
我猜测你有一些enum
像DogBehavior
(有BARK
,BITE
等常量,并且你想确保列表中只允许此类行为。在enum
中收集这些行为的事实是一个实现细节。你应该做的是引入一个指定Behavior
的通用接口。如果没有与Behavior
相关联的任何特定方法,它可能只是一个标记接口(没有定义方法)。否则,您可能希望它有一些方法,例如:
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();
}
这对我来说更有意义。
答案 2 :(得分:1)
我看错了两件事。
首先,您需要将该方法标记为抽象。您没有提供实施。
其次,如果您不想要警告,则应对Enum进行参数化。如果您不需要进一步限制枚举,Enum<?>
就足够了。
然而,正如其他人所说,这可能不是你想要的。 “行为”的枚举对你来说毫无用处。从getBehaviors()返回后,它们没有任何功能。你可以迭代它们并列出它们,但这只值List<String>
。
我认为你想要一个List<Behavior>
,其中行为是一个为你做点什么的接口。
编辑:上面的ColinD在同一点上打败了我。
答案 3 :(得分:0)
public abstract class Animal {
public List<? extends Enum<?>> getBehaviors();
}