Kotlin - только для чтения свойства в интерфейсах - PullRequest
0 голосов
/ 17 ноября 2018

У меня есть этот служебный интерфейс, который должен быть реализован в ViewHolder RecyclerView, который запускает события пользовательского интерфейса.

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 голосов
/ 17 ноября 2018

В Kotlin все свойства интерфейса являются абстрактными, их нельзя инициализировать.Но вы можете иметь собственные методы получения и установки, например:

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

    fun registerListener(listener:V)
    fun unregisterListener (listener: V)
}
0 голосов
/ 17 ноября 2018

Почему вы вообще добавляете свойство в интерфейс? Контракт, который вы хотите определить, - это возможность добавлять и удалять слушателей и, возможно, получить список всех реальных слушателей. Таким образом, интерфейс будет выглядеть так:

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

Если реализация этого интерфейса использует ArrayList, LinkedList или что-то еще для хранения слушателей, это деталь реализации, которой не должно быть в интерфейсе.

0 голосов
/ 17 ноября 2018

Интерфейс, как вы сказали, это Контракт, который вы позволяете всем читать, поэтому нет смысла скрывать свойство, которое является частью этого контракта.

Они (интерфейсы) могут иметь свойства, но они должны быть абстрактными или обеспечивать реализации средства доступа.

Документация по интерфейсу

Итак, как вы сказали, вы можете добиться такого поведения, используя абстрактный класс:

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

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

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