ani*_*der 34 java generics enums
假设我有一个抽象类
public abstract class Trainer<T extends Animal>{}
Run Code Online (Sandbox Code Playgroud)
我有特定的培训师,如:
public DogTrainer extends Trainer<Dog>{}
public HorseTrainer extends Trainer<Horse>{}
Run Code Online (Sandbox Code Playgroud)
这些"训练师"中的每一个都有一套固定的技巧,他们可以训练动物去做,我想使用Enums.所以我有一个界面:
public interface TrainingActions<T extends Animal>{}
Run Code Online (Sandbox Code Playgroud)
在每个培训师中,我都有一个实现此界面的Enum.所以:
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;
}
}
Run Code Online (Sandbox Code Playgroud)
现在在每个Trainer类中,我想要一个方法说'trainingComplete',它将一个Enums作为输入并将其保存到一个集合中.所以
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);}
}
Run Code Online (Sandbox Code Playgroud)
但是,我不想在每个培训师中定义每个特定培训师中的"已完成"集和"培训完成"方法,而是希望父母"培训师"课程中的某些内容可以强制执行Enum类型...所以它是Enums和泛型的奇怪组合.
这可能吗?
Boh*_*ian 28
要指定接口的绑定并且它是枚举,您需要一个通用交集,如下所示:
class MyClass<T extends Enum<T> & SomeInterface> {}
Run Code Online (Sandbox Code Playgroud)
请注意,当与类和接口相交时,该类必须出现在接口之前.
在这种情况下,你想要的仿制功夫是一个更复杂的级别,因为TrainingActions枚举的界面本身必须参考动物类型.
class Trainer<A extends Animal, T extends Enum<T> & TrainingActions<A>> {}
Run Code Online (Sandbox Code Playgroud)
一个完整的工作示例,基于您发布的代码,编译是:
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;
}
}
Run Code Online (Sandbox Code Playgroud)
但我会更进一步,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> {}
Run Code Online (Sandbox Code Playgroud)