我试图覆盖kotlin类中的一个java属性变量,但一直收到错误"myVar什么都不覆盖";。关于如何重写kotlin类的例子在这里,但它没有说明任何关于重写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没有属性,因此需要将字段设为私有字段,并提供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"
}
myVar
是Java中的一个字段,因此不能在Kotlin中重写它。
这样尝试:
//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互操作中的一个问题。
这里有一个破解它:
- 创建一个辅助Java类,隐藏有问题的
protected
字段:
public class myBaseClassKtInterop extends myBaseClass {
private String myVar;
}
- 在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
(如果可能的话(,在这种情况下,您将不需要这个辅助类。