4

我有这个实用程序接口由触发 UI 事件的 RecyclerView 的 ViewHolder 实现。

interface ObservableMvpViewHolder<V> {
    val listeners: List<V>

    fun registerListener(listener:V)
    fun unregisterListener (listener: V)

}

listeners属性就像一个合同,所以我想强制客户声明它来存储观察者。

但是当我实现这个接口时,我必须为这个属性声明一个 getter:

class AddItemViewHolderHolder(override val containerView: View) : ViewHolder(containerView), LayoutContainer, ObservableMvpViewHolder<AddItemViewHolderHolder.Listener> {
        override val listeners: List<Listener>
            get() = listeners

我不想这样做以避免将此属性暴露给外部。

我是 Kotlin 的新手,有没有办法在不必声明抽象类的情况下做到这一点?

4

3 回答 3

3

为什么要将属性添加到界面中?您要定义的合同是添加和删除侦听器的能力,并且可能获取所有实际侦听器的列表。所以界面应该是这样的:

interface ObservableMvpViewHolder<V> {
  fun registerListener(listener:V)
  fun unregisterListener (listener: V)
  fun listeners(): List<V>
}

如果此接口的实现使用 ArrayList、LinkedList 或任何存储侦听器的东西,则该实现细节不应出现在接口中。

于 2018-11-17T12:27:43.063 回答
2

正如您所说,接口是您让每个人都阅读的合同,因此,隐藏属于该合同的属性是没有意义的。

它们(接口)可以具有属性,但这些属性需要是抽象的或提供访问器实现。

接口文档

正如您所说,您可以使用抽象类来实现此行为:

abstract class ObservableMvpViewHolder<V> {
    private val listeners : List<V> = emptyList()

    abstract fun registerListener(listener:V)
    abstract fun unregisterListener (listener: V)

}
于 2018-11-17T05:34:00.630 回答
1

在 Kotlin 中,接口中的所有属性都是抽象的,它们不能被初始化。但是你可以有自定义的 getter 和 setter,例如:

interface ObservableMvpViewHolder<V> {
    val listeners: List<V>
        get() = listOf()

    fun registerListener(listener:V)
    fun unregisterListener (listener: V)
}
于 2018-11-17T07:30:46.193 回答