Intereting Posts
Gson setDateFormat исключает, когда дата равна нулю Модифицировать тело 2 до настраиваемого класса Ссылка конструктора Котлина с дженериками RecyclerView в заголовке другого RecyclerView (Mvvm ​​+ Databinding + Kotlin) Как получить доступ к «Activity.this» в Котлине? Почему Guice не находит привязку List <Interface>? @uncheckedVariance в Котлине? Не удалось передать строковое значение строки в @BindingAdapter в Котлине Добавить фрагмент во время выполнения с причинами Kotlin «К сожалению приложение остановилось» Как класс макета может не соответствовать его классу java в Котлине? Несоответствие параметров параметра Котлина MyBatis с неизменяемыми классами данных в Котлине Иерархия узлов из списка путей каталога Ошибка в android Studio 3.0 при синхронизации градиента. Ошибка. Причина. Не удалось найти допустимый путь сертификации для запрошенной цели. Moshi / Kotlin – Как сериализовать строки NULL JSON в пустые строки?

Как правильно переопределить метод, возвращающий экземпляр родового класса в Котлин

У меня есть абстрактный общий класс:

abstract class BasePresenter<View, Router> { var view: View? = null var router: Router? = null abstract fun OnStart() abstract fun OnStop() } 

И у меня есть подкласс:

 class NewsListPresenter : BasePresenter<NewsListView, MainRouter>() { override fun OnStop() { // } override fun OnStart() { // } } 

Также у меня есть класс с защищенным абстрактным методом:

 protected abstract fun getPresenter() : BasePresenter<Any?, Any?> 

И я переопределяю его в подклассе:

 override fun getPresenter(): BasePresenter<Any?, Any?> { return NewsListPresenter() as BasePresenter<Any?, Any?> } 

Android Studio выделяет переопределенную функцию, говорящую: «Это литье никогда не преуспеет». Я пробовал использовать in Any , out Any и * и он не работает. Когда я пытался использовать * я не мог использовать метод getPresenter() в классе, где он изначально определен. Android Studio жалуется на несоответствие типов: ничего не требуется ?, найдено BaseFragment. В Java тот же код работал бы отлично, и я не думал, что это будет проблемой в Котлине. Каков правильный способ реализации этого?

Предупреждение «литье никогда не может быть успешным» здесь неверно. Правильное сообщение для предупреждения должно быть «снято без следа», потому что это приведение может быть или не быть правильным, но это невозможно обнаружить, запустив вашу программу.

В трекере есть проблема, которая на самом деле была исправлена несколько дней назад. Исправление, скорее всего, приведет его к Kotlin 1.0.3.

Для этого используйте BasePresenter<*,*> .

Из документов :

Star-проекции

Иногда вы хотите сказать, что ничего не знаете о аргументе типа, но все же хотите использовать его безопасным способом. Безопасным способом здесь является определение такой проекции родового типа, что всякое конкретное создание этого родового типа будет подтипом этой проекции.

Kotlin обеспечивает так называемый синтаксис звездной проекции для этого:

Для Foo<out T> , где T является параметром ковариантного типа с верхней границей TUpper , Foo<*> эквивалентен Foo<out TUpper> . Это означает, что когда T неизвестно, вы можете спокойно читать значения TUpper из Foo<*> . Для Foo<in T> , где T – параметр контравариантного типа, Foo<*> эквивалентен Foo<in Nothing> . Это означает, что вы ничего не можете записать в Foo<*> безопасным способом, когда T неизвестно. Для Foo<T> , где T является параметром инвариантного типа с верхней границей TUpper , Foo<*> эквивалентен Foo<out TUpper> для чтения значений и Foo<in Nothing> для записи значений. Если общий тип имеет несколько параметров типа, каждый из них может быть спроецирован независимо. Например, если тип объявлен как интерфейс Function<in T, out U> мы можем представить себе следующие звездные проекции:

Function<*, String> означает Function<in Nothing, String> ; Function<Int, *> означает Function<Int, out Any?> ; Function<*, *> означает Function<in Nothing, out Any?> . Примечание: звездообразные проекции очень похожи на исходные типы Java, но безопасны.