Вывести общий тип из класса реализации - PullRequest
1 голос
/ 03 июля 2019

Предположим, у меня есть абстрактный класс Pipeline<T>, который содержит некоторые элементы типа T и реализующий класс IntPipeline, который расширяет Pipeline<Integer>.

abstract class Pipeline<T> {
  abstract T getNextItem();
}
class IntPipeline extends Pipeline<Integer> {
  Integer getNextItem() {
    // generate integer here
    return 0;
  }
}

Теперь я хочунаписать несколько тестов.Поскольку все реализации Pipeline будут иметь похожие тесты, я хочу создать абстрактный базовый класс для определения некоторых стандартных тестов:

abstract class PipelineTest<S, T extends Pipeline<S>> {

  private final Class<T> clazz;

  protected PipelineTest(Class<T> clazz) {
    this.clazz = clazz;
  }

  abstract T createInstance();

  @Test
  void canBeSerializedAndDeserialzed() {
    var serializer = ...;
    T pipeline = createInstance();
    var json = serializer.toJson(pipeline);
    T deserializedPipeline = serializer.fromJson(json, clazz);
    assertEquals(pipeline, deserializedPipeline);
  }
}

Таким образом, конкретный тест будет выглядеть так:

class IntPipelineTest extends PipelineTest<Integer, IntPipeline> { // redundant information here

  IntPipelineTest() {
    super(IntPipeline.class);
  }

  IntPipeline createInstance() {
    return new IntPipeline();
  }
}

Как видите, когда я создаю конкретный тест, мне нужно передать туда избыточную информацию.Я говорю компилятору, что создам тест для конвейера типа Integer.Насколько я понимаю, это может быть выведено из IntPipeline.Поэтому я подозреваю, что с дженериками я делаю что-то в корне неправильное.

Так есть ли способ реструктурировать код, чтобы я мог создать тест без необходимости объявлять тип расширения Integer?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...