Java 有可能重写Kotlin中的静态方法吗?

Java 有可能重写Kotlin中的静态方法吗?,java,kotlin,Java,Kotlin,你好,想象一下我们有下面的课 Manager{ public static void doSth(){ // some logic }; } 如何在kotlin中重写该方法 我已经用累了 fun Manager.doSth(){} 但它应用于实例而不是静态类型 这样做的目的是避免使用PowerMockito,但在Kotlin中不能这样做。问题是Kotlin中没有static关键字。有一个类似的概念(伴生对象),但问题是您的原始Java类没有 static方法也不支持继

你好,想象一下我们有下面的课

Manager{
   public static void doSth(){
      // some logic
   };
}
如何在kotlin中重写该方法

我已经用累了

fun Manager.doSth(){}
但它应用于实例而不是静态类型


这样做的目的是避免使用PowerMockito,但在Kotlin中不能这样做。问题是Kotlin中没有
static
关键字。有一个类似的概念(
伴生对象
),但问题是您的原始Java类没有

static
方法也不支持继承,因此在Java方面您也无能为力

如果要声明“静态”的扩展方法(例如:将它们放在
伴生对象上),可以执行以下操作:

class Manager {

    companion object
}

fun Manager.Companion.doSth() = println("sth")
然后你可以这样称呼它:

Manager.doSth()

请注意您只能以这种方式扩充Kotlin类,这些类具有
伴生对象简短答案

没有

简短的解释

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

完整解释

  • 无法重写静态方法。这叫做隐藏时的阴影 一种方法与另一种方法相结合
  • Kotlin中没有静态方法,因此您可以使用
    伴生对象
    的行为类似,您可以访问该方法 对伴随对象的访问,就好像它是一个java静态方法,只使用 类名称作为限定符,但不能访问 父类的子类(如Java)的伴生对象
  • 您不能在Kotlin中隐藏静态方法,因为静态方法将无法使用子类限定符,但您可以编写另一个伴生对象,并添加一个具有相同名称的方法,然后调用 由于无法访问来自父级的方法,因此无法从中访问父级方法 使用子类名限定符
  • 您不能创建对伴生对象进行阴影处理的扩展方法 方法,甚至重写成员方法。如果一个类有一个成员 定义了一个函数和一个具有相同 接收方类型,名称相同,适用于给定参数, 会员总是赢的
  • :您可以将扩展方法写入 同伴对象,但如果该同伴对象的成员 该成员将始终赢得相同的签名
例子
开放式A类{
fun foo(){
println(“A.foo()”)
}
伴星{
趣味酒吧(){
println(“A.company.bar()”)
}
}
}
B类:A()
fun A.foo(){
println(“A.foo()扩展名”)
}
有趣的,有趣的{
println(“A.Companion.bar()扩展名”)
}
乐趣A.Companion.baz(){
println(“A.Companion.baz()扩展名”)
}
趣味主线(args:Array){
A().foo()//打印A.foo()
A.bar()//打印A.Companion.bar()
A.baz()//打印A.Companion.baz()扩展名
B.bar()//编译错误
}

您所谓的“覆盖”实际上意味着“替换”,也就是说,对原始声明类进行monkey-patch。无法重写非虚拟方法。多态性和static关键字是相互冲突的概念。你的建议是不可能的,因为它没有意义。我建议你仔细阅读@Marko Topolnik,正确的术语是“阴影”@Pawel阴影更轻,它只会影响非限定名称的分辨率。这不是OP想要的。我以前不知道猴子补丁,但我会读到的。不明白为什么某人否决了它?这个问题是否违反了堆栈溢出规则?如果没有,为什么要这样做?我无论如何都不能重写静态方法。是的,问题是父级的静态方法不能从子级的限定符访问,因此不能对其进行阴影处理。使用扩展,无论是静态的还是非静态的,您都无法做到这一点,因为成员函数总是会赢。您可以做的是对父对象进行子类化,并添加一个新的伴随对象,该对象具有与父对象同名的方法。
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
}