java强制子级使用自己定义的枚举
假设我有一个抽象的动物训练师家长课程:
public abstract class Trainer
<A extends Animal,
E extends Enum<E> & Trainables>{
protected EnumSet<E> completed;
public void trainingComplete(E trainable){
trainingComplete.add(trainable);
}
我希望家长动物培训师的具体扩展,以完成其定义的培训对象的培训。因此,如果我有一个具体的狗教练如下:
public class DogTrainer extends Trainer<Dog, DogTrainer.Tricks>{
public enum Tricks implements Trainables {
FETCH, GROWL, SIT, HEEL;
}
}
使用当前的DogTrainer
定义,我只能对DogTrainer.Tricks
类型的参数执行trainingComplete
。但我想强调,任何创建一个具体的Trainer
的人都应该允许trainingComplete()
为Trainables
定义它自己
换句话说,我当前设计的问题是,如果我有另一个培训师,如下所示:
public class PoliceDogTrainer extends Trainer<Dog, PoliceDogTrainer.Tricks>{
public enum Tricks implements Trainables {
FIND_DRUGS, FIND_BOMB, FIND_BODY;
}
}
没有什么能阻止某人定义另一个试图教狗的胭脂教练,警察把戏:
public class RougeTrainer extends Trainer<Dog, PoliceDogTrainer.Tricks>{
...
}
我想禁止这样做,并允许扩展类只使用他们自己指定的可培训内容
我该怎么做
# 1 楼答案
可以使
enum
的非public
但抽象基类不能强制执行。另一种方法是通过添加必须与Trainer
类匹配的类型参数,使Trainables
成为泛型。这不会强制enum
成为内部类(这是不可能的),但是对于一致性子类,则不能创建RogueTrainer
对基类或接口中的
this
类型强制执行约束介于棘手和不可能之间。一个常见的例子是Comparable
接口,它的声明方式不能阻止像class Foo implements Comparable<String>
这样的实现规避此问题的一种方法是使
Trainer
引用一个参数,例如public static
方法只能通过Trainer
和Trainables
的正确组合来调用。trainingCompleteImpl
方法可以由同一包中的受信任子类调用和重写。如果不希望这样,可以内联方法的代码并完全删除实例方法_
另一种方法是为
Trainer
创建一个类型参数,并在运行时强制该参数与this
匹配:因此,对于不一致的
Trainer
实现selfReference()
不能作为return this;
实现,这很容易被检测到。对于一致性实现,JVM将内联selfReference
方法,并查看this==this
,然后对其进行优化;因此,此检查对性能没有影响