微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

我想让委托类使用在kotlin中委托它的类的属性

如何解决我想让委托类使用在kotlin中委托它的类的属性

我有这两节课:

class InfoDayviewmodel(
    day: Day,application: Application
) : Dayviewmodel(day,application) {
    val dayDeleted = mutablelivedata<Boolean>().apply { value = false }
    fun deleteDay() {
        viewmodelScope.launch {
            repository.deleteDay(day)
            dayDeleted.value = true
        }
    }
}

class InfoIdeaviewmodel(
    idea: Idea,topic: Topic,application: Application
) : Ideaviewmodel(idea,topic,application) {
    val ideaDeleted = mutablelivedata<Boolean>().apply { value = false }
    fun deleteIdea() {
        viewmodelScope.launch {
            repository.deleteIdea(idea)
            ideaDeleted.value = true
        }
    }
}

它们非常相似,但是我不能使用超类,因为它们已经具有超类了。所以我可以创建一个像这样的界面:

interface InfoItemviewmodel {
    val itemDeleted: mutablelivedata<Boolean>
    fun deleteItem()
}

但是,我将不得不在两个类中实现接口的功能,并且我将不得不重复代码。因此,我可以使用composition并创建一个包含接口实现的类:

abstract class InfoItemviewmodelImpl(private val coroutinescope: Coroutinescope) : InfoItemviewmodel {
    override val itemDeleted = mutablelivedata<Boolean>().apply { value = false }
    override fun deleteItem() {
        coroutinescope.launch {
            deleteItemFromDatabase()
            itemDeleted.value = true
        }
    }
    abstract suspend fun deleteItemFromDatabase()
}

并且我可以使两个类都像这样实现此功能

class InfoIdeaviewmodel(
    idea: Idea,application),InfoItemviewmodel {
    private val infoItemviewmodel = object : InfoItemviewmodelImpl(viewmodelScope) {
        override suspend fun deleteItemFromDatabase() { repository.deleteIdea(idea) }
    }
    override val itemDeleted get() = infoItemviewmodel.itemDeleted
    override fun deleteItem() { infoItemviewmodel.deleteItem() }
}

class InfoDayviewmodel(
    day: Day,InfoItemviewmodel {
    private val infoItemviewmodel = object : InfoItemviewmodelImpl(viewmodelScope) {
        override suspend fun deleteItemFromDatabase() { repository.deleteDay(day) }
    }
    override val itemDeleted get() = infoItemviewmodel.itemDeleted
    override fun deleteItem() { infoItemviewmodel.deleteItem() }
}

但是,有很多样板代码,因为在每个类中,我都必须创建一个包含实现的对象,并针对每个属性函数使它使用该对象。

解决这个问题,我想到了这样的委托:

class InfoDayviewmodel(
    day: Day,InfoItemviewmodel by object : InfoItemviewmodelImpl(viewmodelScope) {
    override suspend fun deleteItemFromDatabase() {
        repository.deleteDay(day)
    }
}

但这不起作用。它无法识别viewmodelScope,也无法识别存储库。 InfoItemviewmodelImpl是在InfoDayviewmodel之前创建的,这就是它无法访问这些属性的原因。我该怎么解决

解决方法

这是一种可能的解决方法。如果您在多个类中使用此委托,则它的解决方案要比解决方案的冗长得多。但这不是很优雅,因为age变成了公共读写属性。

interface CanRun {
    fun run(): String
    var age: Int
}

class CanRunImpl : CanRun {
    override var age by Delegates.notNull<Int>()
    override fun run(): String {
        return if (age > 10) "fast" else "slow"
    }
}

class Lion : CanRun by CanRunImpl() {
    init { age = 5 }
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。