Ограничение расширения дженериков в Java, любой способ обойти это? - PullRequest
0 голосов
/ 29 августа 2018

У меня есть следующая модель для создания контроллеров в моем приложении. Очевидно, что полная модель более сложна, но я остановлюсь на единственной части, которая вызывает у меня проблемы:

public abstract AbstractController<T> {
    abstract protected Class<T> getType();
}

public ParentController extends AbstractController<Parent> {
    @Override
    protected Class<Parent> getType() {
        return Parent.class;
    }
}

Теперь я хотел бы расширить родительский объект и иметь контроллер для сына, это выглядело бы так:

public SonController extends ParentController {
    @Override
    protected Class<Son> getType() {
        return Son.class;
    }
}

Проблема в том, что метод getType () показывает несовместимость при компиляции (ожидает класс Parent).

Я пытался поиграть с дженериками, но не могу найти решение. Метод getType используется в нескольких методах от абстрактного контроллера, и я действительно хотел бы избежать их переопределения.

Любые идеи приветствуются.

Ответы [ 2 ]

0 голосов
/ 29 августа 2018

Обобщения являются инвариантными для начала, поэтому Class<Son> нельзя присвоить Class<Parent> (в вашем случае это не ковариантные типы возврата).

Но подстановочный знак с расширением-границей (верхняя граница) делает тип ковариантным , таким образом, это решит его:

public abstract class AbstractController<T> {
    abstract protected Class<? extends T> getType();
}

public class ParentController extends AbstractController<Parent> {
    @Override
    protected Class<? extends Parent> getType() {
        return Parent.class;
    }
}

class SonController extends ParentController {
    @Override
    protected Class<? extends Parent> getType() {
        return Son.class;
    }
}
0 голосов
/ 29 августа 2018

Вы можете изменить getType return Class<? extends T>.

abstract protected Class<? extends T> getType();

Тогда ParentController и SonController будут выглядеть как

public class ParentController extends AbstractController<Parent> {
    @Override
    protected Class<? extends Parent> getType() {
        return Parent.class;
    }
}

public class SonController extends ParentController {
    @Override
    protected Class<? extends Parent> getType() {
        return Son.class;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...