将属性的类型更改为子类中的子类

时间:2019-10-17 19:20:16

标签: generics kotlin

我有一个AbstractListFragment类,其属性类型为AbstractListViewModel。如何将此属性的类型更改为AbstractListFragment的子类中的AbstractListViewModel的子类

我尝试过:

abstract class AbstractListViewModel()

abstract class AbstractListFragment() {
   abstract var viewModel : AbstractListViewModel
}

class ChildListViewModel() : AbstractListViewModel()

class ChildListFragment() {
   override lateinit var viewModel : ChildListViewModel
}

但是,我得到了

  

属性是“ ChildListViewModel”,不是替代类型

2 个答案:

答案 0 :(得分:0)

您可以使用一种视图模型来参数化function isUpper(str){ for(i = 0; i < str.length; i++){ if(str.charAt(i) == str.charAt(i).toUpperCase()){ if(!nonnumeric(str.charAt(i))){ return true; }; }; }; return false; }; 类:

AbstractListFragment

答案 1 :(得分:0)

您的代码中有两个问题

首先, ChildListFragment 需要扩展 AbstractListFragment 以覆盖其字段

class ChildListFragment() : AbstractListFragment() 

第二,您不能使用属性类型的子类覆盖var,因为它会破坏Liskov Substitution principle。如果某些方法需要 AbstractListFragment ,然后在其中传递 ChildListFragment ,则该方法可以将 AbstractListViewModel 的其他子项分配给 viewModel ,并且 ChildListFragment 会中断,因为它完全需要 ChildListFragment

class AnotherChild() : AbstractListFragment()

fun someMethod(AbstractListFragment fragment) {
    fragment.viewModel = AnotherChild() // <= here ChildListFragment would expect ChildListViewModel but would get AnotherChild
}

fun main() {
    someMethod(ChildListFragment())
}

如果要从 ChildListFragment 返回 ChildListViewModel ,则应将 viewModel 更改为val

abstract class AbstractListFragment() {
    abstract val viewModel : AbstractListViewModel
}

class ChildListFragment() : AbstractListFragment() {
    override val viewModel : ChildListViewModel
}

您可以使用如下所示的烘烤Lateinit字段:

class ChildListFragment() : AbstractListFragment() {
    private lateinit var _viewModel: ChildListViewModel

    override val viewModel : ChildListViewModel by lazy {
        _viewModel
    }
}

或者您可以使用其他一些技术,例如MVP(例如,参见Moxy library)。