是否有可能在Kotlin中覆盖静态方法?

时间:2018-07-10 13:16:49

标签: java kotlin

你想像我们有以下课程

Manager{
   public static void doSth(){
      // some logic
   };
}

如何在Kotlin中覆盖该方法?

我已经厌倦了使用

fun Manager.doSth(){}

但是它适用于实例,而不是静态类型。

这样做的目的是避免使用PowerMockito

2 个答案:

答案 0 :(得分:6)

简短回答

“简短”说明

您只能覆盖虚拟方法,还可以在Java中阴影/替换静态方法,但是您不能在Kotlin中阴影“静态”方法,因为静态方法将无法使用子类限定符。而且即使使用扩展方法,您也不能对静态或非静态方法进行操作,因为成员函数将始终获胜(请参见下面的示例)。您可以做的是对父对象进行子类化,并添加一个新的同伴对象,该对象具有与父对象同名的方法,并从内部调用父方法。

完整说明

  • 静态方法不能被覆盖。隐藏时称为阴影 一种方法与另一种方法。
  • Kotlin中没有静态方法,因此您可以使用 companion object的行为类似,您可以访问该方法 伴侣对象,就好像它是仅使用java的静态方法一样 类名作为限定符,但是您无法访问 子类之类的父类的同伴对象。
  • 您无法在Kotlin中隐藏静态方法,因为该静态方法已经无法使用子类限定符使用,但是您可以编写另一个伴随对象并添加具有相同名称的方法并调用 从那里的父方法,因为无法访问父方法 带有子类名称限定符的
  • 您不能创建隐藏伴侣对象的扩展方法 方法甚至覆盖成员方法。如果班级有成员 函数和扩展函数定义相同 接收器类型,具有相同的名称,并且适用于给定的参数, 成员总是赢。
  • Companion object extension:您可以编写扩展方法来 随播对象,但如果该随播对象的成员具有 成员将永远赢得相同的签名。

示例

class A {
    fun foo() {
        println("A.foo()")
    }
    companion object {
        fun bar() {
            println("A.Companion.bar()")
        }
    }
}

fun A.foo() {
   println("A.foo() extension")
}

fun A.Companion.bar() {
    println("A.Companion.bar() extension")
}

fun A.Companion.baz() {
    println("A.Companion.baz() extension")
}

fun main(args: Array<String>) {
    A().foo() // prints A.foo()
    A.bar() // prints A.Companion.bar()
    A.baz() // prints A.Companion.baz() extension
}

答案 1 :(得分:2)

您无法在Kotlin中做到这一点。问题是Kotlin中没有static关键字。有一个类似的概念(companion object),但问题是您的原始Java类没有一个。

static方法也不支持继承,因此在Java方面您无济于事。

如果要声明“静态”扩展方法(例如:将其放在companion object上),则可以执行以下操作:

class Manager {

    companion object
}

fun Manager.Companion.doSth() = println("sth")

然后您可以这样称呼它:

Manager.doSth()

请注意,您只能通过拥有 companion object的方式来扩展 Kotlin 类。