假设我有一个抽象类
public abstract class Trainer<T extends Animal>{}
我有一些特定的培训师,例如:
public DogTrainer extends Trainer<Dog>{} public HorseTrainer extends Trainer<Horse>{}
这些“训练者”中的每一个都有一套固定的技巧,他们可以训练动物去做,我想用枚举来做。所以我有一个接口:
public interface TrainingActions<T extends Animal>{}
在每个培训师中,我都有一个实现此接口的枚举。所以:
public DogTrainer extends Trainer<Dog>{ public enum Trainables implements TrainingActions<Dog>{ BARK, BITE, ROLLOVER, FETCH; } } public HorseTrainer extends Trainer<Horse>{ public enum Trainables implements TrainingActions<Horse>{ JUMP, TROT, REARUP; } }
现在,在每个Trainer类中,我想要一个方法“ trainingComplete”,该方法以枚举之一作为输入并将其保存到集合中。所以
public DogTrainer extends Trainer<Dog>{ public enum Trainables implements TrainingActions<Dog>{ BARK, BITE, ROLLOVER, FETCH; } public Set<Trainables> completed = new HashSet<Trainables>(); public void trainingComplete(Trainables t){completed.add(t);} }
但是,我不想在每个特定的培训师中定义“完成”集,也不在每个培训师中定义“ trainingComplete”方法,而是希望在父“ Trainers”类中可以采用Enum类型强制执行的操作…因此,这是枚举和泛型的怪异组合。
这可能吗?
要指定接口的绑定并使其成为枚举,您需要一个通用 交集 ,该 交集 如下所示:
class MyClass<T extends Enum<T> & SomeInterface> {}
请注意,在将一个类和一个接口相交时,该类必须出现在接口之前。
在这种情况下,所需的通用功夫要复杂一个级别,因为TrainingActions枚举的接口本身必须引用动物类型。
class Trainer<A extends Animal, T extends Enum<T> & TrainingActions<A>> {}
根据您发布的代码,一个完整的工作示例可以编译为:
public class Animal {} public interface TrainingActions<T extends Animal> {} /** * A trainer that can teach an animal a suitable set of tricks * @param <A> The type of Animal * @param <T> The enum of TrainingActions that can be taught to the specified Animal */ public abstract class Trainer<A extends Animal, T extends Enum<T> & TrainingActions<A>> { private Set<T> completed = new HashSet<T>(); public void trainingComplete(T t) { completed.add(t); } } public class Dog extends Animal {}; public class DogTrainer extends Trainer<Dog, DogTrainer.Trainables> { public enum Trainables implements TrainingActions<Dog> { BARK, BITE, ROLLOVER, FETCH; } }
但是,我将更进一步,并TrainingActions在Animal它们适用的特定类中定义几个枚举:
TrainingActions
Animal
public class Dog extends Animal { public enum BasicTrainables implements TrainingActions<Dog> { SIT, COME, STAY, HEEL; } public enum IntermediateTrainables implements TrainingActions<Dog> { BARK, BITE, ROLLOVER, FETCH; } public enum AdvacedTrainables implements TrainingActions<Dog> { SNIFF_DRUGS, FIND_PERSON, ATTACK, GUARD; } }; public class PuppyTrainer extends Trainer<Dog, Dog.BasicTrainables> {} public class ObedienceTrainer extends Trainer<Dog, Dog.IntermediateTrainables> {} public class PoliceTrainer extends Trainer<Dog, Dog.AdvacedTrainables> {}