使用方法扩展和继承时名称冲突
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")
.
指向扩展方法
我有一个扩展
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")
.