Kotlin 类的调用方法

Posted

技术标签:

【中文标题】Kotlin 类的调用方法【英文标题】:Call method from Kotlin class 【发布时间】:2017-01-22 05:27:12 【问题描述】:

我有一个 util Kotlin 类,我在其中设置工具栏标题、隐藏或显示工具栏取决于片段:

class MyToolbarUtils() 

    fun hideToolbar(activity: Activity) 
        (activity as MainActivity).supportActionBar!!.hide()
    

    fun showToolbar(activity: Activity, tag: String) 
        setToolbarTitle(tag, activity)
        (activity as MainActivity).supportActionBar!!.show()
    

    fun setToolbarTitle(tag: String, activity: Activity) 
        var title = ""
        when (tag) 
            "Main_fragment" -> title = activity.resources.getString(R.string.Main_screen)
            "Add_note" -> title = activity.resources.getString(R.string.Add_note)
        
        activity.title = title
    

如何从 Fragment 调用 showToolbar(...)? 我刚试过MyToolbarUtils.showToolbar(..),但不可能

我发现只有一种方法是:

val setToolbarTitle = MyToolbarUtils()
setToolbarTitle.showToolbar(activity, tag)

但必须有更好的方法来做到这一点..

【问题讨论】:

Kotlin 有静态方法吗?如果不是,那么您所展示的内容是有道理的 如果所有这些都只适用于一个类,MainActivity 为什么它们就不是那个类的方法? 您询问了xy question ...您决定了一个编程问题的答案,然后使用该预先决定的答案寻求帮助。但在这种情况下,您的答案根本不是正确的。在这种情况下,惯用的 Kotlin 不会使用静态或对象声明,而是使用 ***.com/a/39499145/3679676 【参考方案1】:

将您的 class 转换为 object,它的工作原理应该类似于 java 静态方法。

您可以在此处获取更多信息:https://kotlinlang.org/docs/reference/object-declarations.html#object-declarations

【讨论】:

那么如何从片段和适配器调用该函数?? @chandanicpatel...Class.Method() 或使用上面的示例...MyToolbarUtils.showToolbar()。 OP把这个放在他的问题中【参考方案2】:

听起来像MyToolbarUtils 应该是object declaration 而不是类。

另一种方法是在文件的顶层(而不是在任何类中)声明此类内部的函数,并通过它们的简单名称来引用它们。

【讨论】:

【参考方案3】:

其他人回答了如何让你的函数感觉像静态方法,但对于这个用例,你有一个更惯用的选择。

Kotlin 中的扩展函数替换 Java 中的静态实用程序类:

既然你的所有函数都将Activity作为参数,为什么不使用extension functions并让它们扩展ActivityMainActivity类呢?

fun MainActivity.hideToolbar() 
    supportActionBar!!.hide()


fun MainActivity.showToolbar(tag: String) 
    setToolbarTitle(tag)
    supportActionBar!!.show()


fun Activity.setToolbarTitle(tag: String) 
    title = when (tag) 
        "Main_fragment" -> title = resources.getString(R.string.Main_screen)
        "Add_note" -> title = resources.getString(R.string.Add_note)
        else -> "" // or did you mean this to be an exception?
    

现在它们都在您的 MainActivityActivity 类的上下文中(this 现在是其中之一的实例),您不必在其他不相关的 @987654332 中寻找它们@ 班级。每当您在活动类中时,您都可以简单地:

showToolbar("Main_fragment")

或从您引用某个活动的其他地方:

// you have a reference of MainActivity type
myMainActivity.showToolbar("Main_fragment")

// you have a reference you can cast to MainActivity type
(someActivity as MainActivity).showToolbar("Main_fragment")

// this function works with any Activity
someActivity.setToolbarTitle("Add_note")

还要注意,我清理了一点代码,用when as an expression设置标题,还去掉了var(需要var的时候很少见,所以总要想想怎么工作与val)。作为表达式,when 将需要一个 else 子句,所以我将其设置为与您默认的 "" 空字符串相同。

类方法的替代方案:

由于所有 3 种方法都需要 MainActivity 的实例(基于它们的转换),为什么不将它们作为成员函数放入 MainActivity

class MainActivity ... 
    ...

    fun hideToolbar() 
        supportActionBar!!.hide()
    

    fun showToolbar(tag: String) 
        setToolbarTitle(tag)
        supportActionBar!!.show()
    

    fun setToolbarTitle(tag: String) 
        title = when (tag) 
            "Main_fragment" -> title = resources.getString(R.string.Main_screen)
            "Add_note" -> title = resources.getString(R.string.Add_note)
            else -> "" // or did you mean this to be an exception?
        
    

并从对MainActivity 的任何引用中调用它们。

作为对象声明的替代方案:

最后,正如其他人所建议的那样,为了完整起见,这里它们位于一个实用程序类中,其作用类似于静态变量,而是单例 object declaration 上的方法:

object MyToolbarUtils() 
    fun hideToolbar(activity: MainActivity) 
        activity.supportActionBar!!.hide()
    

    fun showToolbar(activity: MainActivity, tag: String) 
        setToolbarTitle(activity, tag)
        activity.supportActionBar!!.show()
    

    fun setToolbarTitle(activity: Activity, tag: String) 
        activity.title = when (tag) 
            "Main_fragment" -> title = resources.getString(R.string.Main_screen)
            "Add_note" -> title = resources.getString(R.string.Add_note)
            else -> "" // or did you mean this to be an exception?
        
    

但我认为这是扩展另一个类的功能的最糟糕和最不像 Kotlin 的方式。像 SomethingUtils 这样充满静态的类/对象意味着您可能应该改写 extension functions。

【讨论】:

【参考方案4】:

使用 object 关键字在 Kotlin 中创建一个单例类,并在 Java 中调用 Kotlin 单例类,如下所示:

object SampleSingleton 
   fun someMethod()  
     println("I love coding")
   

如果来自Java则如下

public static void main(String args[]) 
   SampleSingleton.INSTANCE.someMethod();

或来自 Kotlin 类如下

SampleSingleton.someMethod()

【讨论】:

【参考方案5】:

我不确定这是否符合您对更好方法的定义,但更简单的方法是替换您的两行代码:

val setToolbarTitle = MyToolbarUtils()
setToolbarTitle.showToolbar(activity, tag)

只有这一行;

MyToolbarUtils().showToolbar(activity, tag)

编码愉快!

【讨论】:

【参考方案6】:
// Kotlin

@file:JvmName("DemoUtils")
package demo

class ClassInKotlin

fun methodInKotlin() 


// Java
new demo.ClassInKotlin();
demo.DemoUtils.methodInKotlin();

试试这个。这应该可以。

【讨论】:

这真的没有意义。他不是试图从 Java 调用代码,你也不需要@JvmName 没有ClassInKotlin 也不需要来自 Java 的调用。

以上是关于Kotlin 类的调用方法的主要内容,如果未能解决你的问题,请参考以下文章

Kotlin学习之路:继承

如何在 kotlin 中使用非静态方法?

深入kotlin - 与Java互操作:java调用kotlin

深入kotlin - 与Java互操作:java调用kotlin

深入kotlin - 与Java互操作:java调用kotlin

深入kotlin - 与Java互操作:java调用kotlin