У меня есть универсальный интерфейс с реализацией внутри него:
@FunctionalInterface
public interface PlayerPickStrategy<T> {
static <T> PlayerPickStrategy<T> always1() {
return new AlwaysOne<>();
}
int getNextPick(T lastResult);
final class AlwaysOne<T> implements PlayerPickStrategy<T> {
@Override
public int getNextPick(T lastResult) {
return 1;
}
}
}
Затем я получил две другие реализации этого в отдельных классах, которые неявно типизированы:
public class SimulationRunRandomFromPayoutsSizePlayerPickStrategy implements PlayerPickStrategy<Integer> {
private final RandomRng randomRng = new RandomRng();
public static SimulationRunRandomFromPayoutsSizePlayerPickStrategy random() {
return new SimulationRunRandomFromPayoutsSizePlayerPickStrategy();
}
@Override
public int getNextPick(Integer sizeOfPayouts) {
return randomRng.getRandomNumber(false, 1, sizeOfPayouts);
}
}
public class SimulationRunNextNodePlayerPickStrategy implements PlayerPickStrategy<IPlayResult> {
private Map<String, Integer> picksForModes;
SimulationRunNextNodePlayerPickStrategy(Map<String, Integer> picksForModes) {
this.picksForModes = picksForModes;
}
static SimulationRunNextNodePlayerPickStrategy nextNode(Map<String, Integer> picksForModes) {
return new SimulationRunNextNodePlayerPickStrategy(picksForModes);
}
@Override
public int getNextPick(IPlayResult playResult) {
String nextState = playResult.getNextState().toString();
return picksForModes.get(nextState);
}
}
Я сопоставляю вход String с одним из этих PlayerPickStrategies следующим образом:
public static PlayerPickStrategy getPlayerPickStrategy(String playerPickStrategy) {
// RANDOM="1,2,3,4"
// ALWAYS="2"
// NEXT_MODE="gf44fdgf":"1","fgdfgdfgdf":"7"
String[] playerPickStrategySplit = playerPickStrategy.split("=");
return SimulationPicks.valueOf(playerPickStrategySplit[0]).getStrategy(playerPickStrategySplit[1]);
}
public enum SimulationPicks {
RANDOM(s -> PlayerPickStrategy.randomOf(Arrays.stream(s.split(","))
.map(Integer::parseInt)
.collect(Collectors.toList()))),
RANDOM_FROM(s-> SimulationRunRandomFromPayoutsSizePlayerPickStrategy.random()),
FIXED_ORDER(s -> PlayerPickStrategy.randomOf(Arrays.stream(s.split(","))
.map(Integer::parseInt)
.collect(Collectors.toList()))),
ALWAYS_N(s -> PlayerPickStrategy.always(Integer.parseInt(s))),
NEXT_NODE(s -> SimulationRunNextNodePlayerPickStrategy.nextNode(Stream.of(s.split(","))
.map(it -> it.split(":"))
.collect(Collectors.toMap(it -> it[0].replace("\"", ""),
it -> Integer.parseInt(it[1])))));
final Function<String, PlayerPickStrategy> mapper;
SimulationPicks(Function<String, PlayerPickStrategy> mapper) {
this.mapper = mapper;
}
public PlayerPickStrategy getStrategy(String input) {
return mapper.apply(input);
}
}
Таким образом, я получаю объект PlayerPickStrategy, который является одной из 3 реализаций интерфейса и имеет либо T, IPlayResult или Integer.
Однако, когда я пытаюсь вызвать getNextPick с IPlayResult для моего универсального PlayerPickStrategy, он вызывает исключение MethodNotFound для getNextPick (Object), так как метод getNextPick в PlayerPickStrategy ожидает TlastResult, а не IPlayResult.
- Использую ли я универсальные интерфейсы совершенно неправильно?
- Как я должен обрабатывать создание этих универсальных типов и вызов метода, который я 'Я ожидаю, что будет вести себя по-разному в зависимости от типа?
- Как я должен знать, какой тип отправить его доя это называю? Мне может понадобиться отправить ему IPlayResult, или Integer, или вообще ничего, и как лучше всего справиться с этим? instanceof?
Это новая территория для меня, поэтому любая помощь будет принята с благодарностью.