Kotlin-接口中的只读属性

时间:2018-11-17 02:20:23

标签: android kotlin

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

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

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

}

listeners属性就像一个合同,因此我想让客户有义务声明它来存储观察者。

但是当我实现此接口时,我必须为此属性声明一个吸气剂:

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

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

我是Kotlin的新手,有没有一种方法可以不必声明抽象类?

3 个答案:

答案 0 :(得分:3)

为什么要将属性添加到界面中呢?您要定义的合同是添加和删除侦听器的功能,并且可能获得所有实际侦听器的列表。因此界面如下:

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

如果此接口的实现使用ArrayList,LinkedList或用于存储侦听器的任何内容,则是实现细节,不应在接口中出现。

答案 1 :(得分:2)

您所说的接口是每个人都可以阅读的合同,因此,隐藏作为该合同一部分的财产没有意义。

  

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

Interface Documentation

因此,您已经说过,可以使用抽象类来实现此行为:

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

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

}

答案 2 :(得分:1)

在Kotlin中,接口中的所有属性都是抽象的,因此无法初始化。但是您可以使用自定义的getter和setter,例如:

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

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