如何覆盖科特林中的 java class 属性 变量

How to override a java class property variable in kotlin

我试图在我的 kotlin class 中覆盖一个 java 属性 变量,但一直收到错误“myVar 不覆盖任何内容”。如何覆盖 kotlin class 的示例是 here 但它没有说明任何关于覆盖 java 属性的内容。这是代码:

//Java
public class myBaseClass{
    protected String myVar = "hello";

    public myBaseClass(){
    }

    protected void myOneMethod(){
        System.out.println(myVar);
    }
}


//Kotlin
class myChildClass() : myBaseClass() {
    override var myVar = "hi"

    override fun myOneMethod()
    {
        System.out.println(myVar)
    }
}

Java 中的字段不能以任何方式覆盖。由于 myVar 是 Java 中的一个字段,因此无法在 Kotlin 中覆盖它。

由于 Java 没有属性,您需要将该字段设为私有并提供 getter 和 setter。然后在 Kotlin 中,您可以覆盖 getter 和 setter。这不是很漂亮,但这也是您在 Java 子类中必须这样做的方式。您需要另一个私有 属性 来为您的子类实现创建新的支持字段。

public class MyBaseClass {
    private String myVar = "hello";

    public MyBaseClass(){
    }

    protected String getMyVar() {
        return myVar;
    }

    protected void setMyVar(String myVar) {
        this.myVar = myVar;
    }

    protected void myOneMethod(){
        System.out.println(getMyVar());
    }
}
class MyChildClass : MyBaseClass() {
    private var overriddenMyVar: String? = "hi"

    override fun getMyVar(): String? {
        return overriddenMyVar
    }

    override fun setMyVar(myVar: String?) {
        overriddenMyVar = myVar
    }
}
fun main() {
    val x : MyBaseClass = MyChildClass()
    x.myOneMethod() // Prints "hi"
}

这样试试:

//Kotlin
class KotlinImplementation: MyBaseClass() {
    init {
        myVar = "ji"
    }
}

//Java
public class MyBaseClass {
    protected String myVar = "hello";

    public MyBaseClass(){
    }

    protected void myOneMethod(){
        System.out.println(myVar);
    }
}

看起来像是 Java 互操作中的问题。

这里有一个克服它的技巧:

  1. 创建辅助 Java class,隐藏有问题的 protected 字段:
public class myBaseClassKtInterop extends myBaseClass {
    private String myVar;
}
  1. 在科特林中扩展它;还可以考虑为方法添加 public 修饰符,覆盖 protected 修饰符(如果你不这样做,方法 will remain protected;默认 public 可见性不是在这种情况下工作):
class myChildClass : myBaseClassKtInterop() {
    var myVar = " hi"

    public override fun myOneMethod() {
        println(myVar)
    }
}

现在两种访问 myVar 的方法都可以使用:

myChildClass().myOneMethod()  //hi
println(myChildClass().myVar) //hi

另请注意,如果有其他方法访问 myBaseClass 中的 myVar,它们将使用 "hello" 值。也可以考虑覆盖所有这些,或者直接将 myBaseClass 中的 myVar 可见性更改为 private(如果可能的话),在这种情况下,您将不需要此辅助 class。