Один из вариантов - добавить абстрактный метод, который переопределяется в подклассе, чтобы получить правильный тип класса:
public abstract class AnimalService<T extends Animal> {
public T callAPI() {
return restTemplate.getForObject(url, getAnimalClass(), params);
}
abstract Class<T> getAnimalClass();
}
public class SalmonService extends FishAnimalService<Salmon> {
Class<Salmon> getAnimalClass() {
return Salmon.class;
}
}
Другой вариант - ввести переменную экземпляра.
abstract class AnimalService<T extends Animal> {
private Class<T> animalClass;
protected AnimalService(Class<T> animalClass) {
this.animalClass = animalClass;
}
public T callAPI() {
return restTemplate.getForObject(url, animalClass, params);
}
}
public class FishService<T extends Fish> extends AnimalService<Fish> {
protected FishService(Class<T> fishClass) {
super(fishClass);
}
}
public class SalmonService extends FishAnimalService<Salmon> {
public SalmonService() {
super(Salmon.class);
}
}