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
}