首页 > 解决方案 > 是否可以在 Kotlin 中覆盖静态方法?

问题描述

你好想象我们有以下课程

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

如何在 kotlin 中覆盖该方法?

我已经厌倦了使用

fun Manager.doSth(){}

但它应用于实例不是静态类型。

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

标签: javakotlin

解决方案


简答

“短”的解释

您只能覆盖虚拟方法,也可以在 Java 中隐藏/替换静态方法,但不能在 Kotlin 中隐藏“静态”方法,因为静态方法将无法使用子类限定符。即使使用扩展方法,你也不能为静态或非静态做这件事,因为成员函数总是会赢(见下面的例子)。您可以做的是对父对象进行子类化并添加一个新的伴随对象,该对象具有与父对象同名的方法,并从内部调用父方法。

完整说明

  • 静态方法不能被覆盖。当你用另一个方法隐藏一个方法时,它被称为阴影。
  • Kotlin 中没有静态方法,因此您可以使用 companion object行为类似的方法,您可以访问伴生对象的方法,就好像它是仅使用类名作为限定符的 java 静态方法一样,但您不能从父类的子类(如 Java)访问父类的伴生对象的方法。
  • 您不能在 Kotlin 中隐藏静态方法,因为静态方法在使用子类限定符时将不可用,但您可以编写另一个伴随对象并添加同名方法并从那里调用父方法作为方法from parent 不能使用子类名限定符访问。
  • 您不能创建隐藏伴随对象方法甚至覆盖成员方法的扩展方法。如果一个类有一个成员函数,并且定义了一个扩展函数,它具有相同的接收器类型、相同的名称并且适用于给定的参数,则成员总是获胜。
  • 伴随对象扩展:您可以为伴随对象编写扩展方法,但如果该伴随对象的成员具有相同的签名,则该成员将始终获胜。

例子

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

class B: A()

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
    B.bar() // COMPILE ERROR
}

推荐阅读