Конфликты имен при использовании расширения метода и наследования - PullRequest
0 голосов
/ 18 февраля 2019

У меня есть расширение

fun Fragment.showToast(message: String, toastLength: Int = Toast.LENGTH_SHORT) {
    Toast.makeText(context, message, toastLength).show()
}

В проекте мы используем MVP:

interface MyContract {
    interface View {
        fun showToast(message: String)
    }
}

class MyFragment : Fragment(), MyContract.View {
    override fun showToast(message: String) {
        showToast(message)
    }
}

Так что в MyFragment.showToast(message) я ожидаю вызова функции расширения вместо StackOverflowException.

Можно ли вызвать функцию расширения напрямую?Что-то вроде:

Fragment.showToast(this, message)

или мне просто нужно дать другое имя?

Ответы [ 3 ]

0 голосов
/ 18 февраля 2019

Вы можете преобразовать свой класс MyFragment во Fragment и выполнить:

class MyFragment : Fragment(), MyContract.View {
    override fun showToast(message: String) {
        val fragment = this as Fragment
        fragment.showToast(message)
    }
}

Таким образом, вы будете обращаться к функции расширения Fragment class

0 голосов
/ 18 февраля 2019

Методы экземпляра имеют приоритет над функциями расширения, в случае конфликта сигнатур, поэтому ожидаемое поведение является ожидаемым.

Вы можете напрямую обратиться к shadowed импорту функции расширенияэто с псевдонимом: представьте, что у вас есть файл FragmentExt.kt, содержащий метод расширения в пакете с именем mypkg:

package mypkg

fun Fragment.showToast(message: String, toastLength: Int = Toast.LENGTH_SHORT) {
    Toast.makeText(context, message, toastLength).show()
}

Итак, вы можете вызвать функцию расширения (избегая вызова метода экземпляра) следующим образом:

import mypkg.showToast as extShowToast
val fragment : Fragment = ...
fragment.extShowToast(message)

Этот подход работает как в подклассе MyFragment, так и в любом клиентском классе.

В коде Java вы можете сделать что-то похожее, используя метод расширения Kotlin как статический метод.для имен классов по имени файла: если ваша функция расширения находится в FragmentExt.kt, код Java может указывать на метод расширения, используя FragmentExtKt.showToats("Message here").

0 голосов
/ 18 февраля 2019

У вас есть два метода, которые вы можете вызвать для экземпляра Fragment с точно таким же именем и параметрами.

Нет способа определить, какой из них вы хотите вызвать.

Я бы поменял имя одного.

Например

fun Fragment.toast(message: String, toastLength: Int = Toast.LENGTH_SHORT) {
    Toast.makeText(context, message, toastLength).show()
}
...