Переопределение абстрактного свойства суперкласса приводит к ошибке типа - PullRequest
0 голосов
/ 09 мая 2018

Я боролся с этой проблемой пару часов и не нашел решения. Я создаю приложение для Android с использованием шаблона MVP и DataBinding, и я хотел уменьшить стандартный код создания фрагментов с определенной привязкой с использованием определенного Presenter.

Поэтому я объявил следующий абстрактный класс:

abstract class AbstractBoundFragment : Fragment(), Screen {

    protected abstract var presenter: Presenter<Screen>
    protected abstract var binding: ViewDataBinding

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        binding = getBinding(inflater, container)
        return binding.root
    }

    override fun onAttach(context: Context) {
        super.onAttach(context)
        presenter.attachScreen(this)
    }

    override fun onDetach() {
        presenter.detachScreen()
        super.onDetach()
    }

    protected abstract fun getBinding(inflater: LayoutInflater, container: ViewGroup?): ViewDataBinding
}

Когда я расширяю этот класс в конкретном фрагменте, я получаю следующий тип error :

"Var-property type is 'FragmentArtistListBinding', which is not a type of overridden protected abstract var binding: ViewDataBinding defined in xy.z.ui.utils.AbstractBoundFragment."

FragmentArtistListBinding - это класс, созданный привязкой данных Android, и он явно расширяет ViewDataBinding. Я получаю ту же ошибку для переопределенного докладчика. ArtistsPresenter extends класс abstract Presenter<Screen> правильно.

class ArtistListFragment : AbstractBoundFragment(),
    ArtistListScreen {

    @Inject
    override lateinit var presenter: ArtistsPresenter // type error here
    override lateinit var binding: FragmentArtistListBinding // and type error here

    override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentArtistListBinding {
        return FragmentArtistListBinding.inflate(inflater, container, false)
    }

    override fun showArtist(artistName: String) {
        // do stuff
    }

}

Что мне здесь не хватает?

1 Ответ

0 голосов
/ 09 мая 2018

В отличие от val, который является ковариантным, тип var является инвариантным. Подумайте о следующем случае:

abstract class Base {
    abstract var x: Any
}

class Derived : Base {
    override var x: String
}

fun main() {
    val base: Base = Derived()
    base.x = 1
}

Base.x - это Any, так почему бы вам не присвоить Int значение 1? Но ясно, что это неправильно, потому что вы делаете это с экземпляром Derived.

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