使用方法扩展和继承时名称冲突

Name conflicts when using Method extension and Inheritance

我有一个扩展

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) 中我希望调用扩展函数而不是 WhosebugException

是否可以直接调用扩展函数?类似于:

Fragment.showToast(this, message)

或者我只需要提供另一个名字?

您有两个方法可以在具有完全相同的名称和参数的 Fragment 实例上调用。

没法区分你想叫哪一个

我会更改其中一个的名称。

例如

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

您可以将 MyFragment class 转换为 Fragment 并执行:

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

这样你会引用Fragment的扩展函数class

在签名冲突的情况下,实例方法优先于扩展函数,因此您遇到的行为是预期的行为。

你可以直接引用 shadowed 扩展函数,用别名导入它:假设你有一个文件 FragmentExt.kt 包含名为 [=13 的包中的扩展方法=]:

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 subclass 和任何客户端 class.

中都有效

在 Java 代码中,您可以通过将 Kotlin 扩展方法作为静态方法访问 class 文件名上的静态方法来做类似的事情:如果您的扩展函数在 FragmentExt.kt, Java 代码可以使用 FragmentExtKt.showToats("Message here").

指向扩展方法