Как вернуть суперкласс в запросе Android Room?

Я создаю несколько типов отчетов (день, неделя, месяц) из запроса SQL. Отчеты имеют одинаковые атрибуты, но охватывают другой период и имеют общую структуру заголовков. Чтобы решить эту проблему, я использовал Report как абстрактный класс, который определяет атрибуты и требуемые методы.

Моя цель - структурировать свой код таким образом, чтобы я мог использовать класс Report, чтобы извлечь выгоду из полиморфизма. Я хочу иметь возможность преобразовывать подклассы обратно в исходный суперкласс, чтобы мой PagedListAdapter мог обрабатывать несколько типов отчетов. Как я могу этого добиться? Я пытался использовать подстановочный знак, но безуспешно.

Причина, по которой я заменяю экземпляр LiveData, заключается в том, чтобы убедиться, что только один LiveData подписан на PagedListAdapter.

ReportDao.java

@Dao
public abstract class ReportDao {

    @Query(...)
    abstract DataSource.Factory<Integer, Week> getWeekReports();

    @Query(...)
    abstract DataSource.Factory<Integer, Month> getMonthReports();

    @Query(...)
    abstract DataSource.Factory<Integer, Year> getYearReports();

}

ReportsViewModel

public class ReportsViewModel extends ViewModel {

    private static final int TYPE_WEEK = 0;
    private static final int TYPE_MONTH = 1;
    private static final int TYPE_YEAR = 2;

    private final ReportDao reportDao;

    private LiveData<PagedList<Report>> reports;

    public ReportsViewModel(ReportDao reportDao) {
        this.reportDao = reportDao;
    }

    public LiveData<PagedList<Report>> getReports(int type) {
        switch (type) {
            case TYPE_WEEK:
                reports = new LivePagedListBuilder<>(reportDao.getWeekReports(), 20)
                        .build(); // this wont compile
            case TYPE_MONTH:
                ....
        }

        return reports;
    }

}

Какую именно ошибку компиляции вы получаете?

CommonsWare 20.04.2018 23:32

@CommonsWare "несовместимые типы". Что ж, на самом деле это не ошибка компилятора, но IDE показывает ее еще до попытки компиляции.

tomwassing 20.04.2018 23:37

Я предполагаю, что вы столкнулись с классическая проблема ковариации Java. Вы не можете назначить List<Dog> переменной List<Animal>, поскольку List<Animal> подразумевает, что вы можете добавить к ней new Cat(), а List<Dog> не любит кошек. Используя что-то вроде List, вы всегда можете самостоятельно составить список замены, указав правильный тип (например, собрать ArrayList<Animal> и заполнить его своими собаками). Однако я не знаю, как вы это сделаете с DataSource.Factory.

CommonsWare 20.04.2018 23:47

FWIW, я подал по этому поводу запрос функции.

CommonsWare 21.04.2018 00:06

@CommonsWare Ты действительно потрясающий! Спасибо! Я буду следить за выпуском.

tomwassing 21.04.2018 00:17

Комментарий Yiğit в этом выпуске компилируется для меня, хотя сейчас я не в состоянии провести полный тест.

CommonsWare 22.04.2018 09:47
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
3
6
259
0

Другие вопросы по теме