简体   繁体   中英

How to override a java class property variable in kotlin

I am trying to override a java property variable in my kotlin class but keep getting the error "myVar overrides nothing". The example of how to override a kotlin class is here but it doesn't say anything about overriding java properties. Here is the code:

//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)
    }
}

Since Java doesn't have properties, you need to make the field private and provide a getter and setter. Then in Kotlin, you can override the getter and setter. It's not pretty, but this is how you would have to do it in a Java subclass as well. You need another private property to create the new backing field for your subclass implementation.

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"
}

Fields in Java cannot be overridden in any way. Since myVar is a field in Java, it cannot be overridden in Kotlin.

Try like that:

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

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

    public MyBaseClass(){
    }

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

Looks like an issue in Java interop.

Here is a hack to overcome it:

  1. Create an auxilary Java class, hiding problematic protected field:
public class myBaseClassKtInterop extends myBaseClass {
    private String myVar;
}
  1. In kotlin extend it; also consider adding public modifier for method, overring the protected one (if you don't do it, method will remain protected ; default public visibility is not working in this case):
class myChildClass : myBaseClassKtInterop() {
    var myVar = " hi"

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

Now both ways to access myVar are working:

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

Also note that if there were another methods, accessing myVar in myBaseClass , they will be working with "hello" value. Consider overriding all of them too, or change myVar visibility to private in myBaseClass directly (if it is possible), in this case you will not need this auxilary class.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM