如何在 Kotlin 中覆盖 Java 类的属性变量

huangapple go评论89阅读模式
英文:

How to override a java class property variable in kotlin

问题

这是代码的翻译部分:

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

记得检查一下代码,看看是否有任何问题。

英文:

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

答案1

得分: 5

因为Java没有属性(properties),你需要将字段设为私有,并提供一个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() // 输出 "hi"
}
英文:

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

答案2

得分: 3

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

英文:

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

答案3

得分: 2

尝试像这样:

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

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

    public MyBaseClass() {
    }

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

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

</details>



# 答案4
**得分**: 0

看起来是Java互操作性方面的问题。

以下是一个解决方法:
1. 创建一个辅助的Java类,隐藏有问题的`protected`字段:

```lang-java
public class myBaseClassKtInterop extends myBaseClass {
    private String myVar;
}
  1. 在Kotlin中扩展它;还要考虑为方法添加public修饰符,覆盖protected的方法(如果不这样做,方法将保持protected;在这种情况下,默认的公共可见性不起作用):
class myChildClass : myBaseClassKtInterop() {
    var myVar = "hi"

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

现在两种访问myVar的方式都可行:

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

还要注意,如果在myBaseClass中有另外的方法访问myVar,它们会使用值"hello"。考虑同时覆盖它们,或直接将myVar的可见性在myBaseClass中改为private(如果可能的话);在这种情况下,你将不需要这个辅助类。

英文:

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 = &quot; hi&quot;

    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 &quot;hello&quot; 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.

huangapple
  • 本文由 发表于 2020年10月17日 06:17:00
  • 转载请务必保留本文链接:https://go.coder-hub.com/64397076.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定