2
votes
interface MyInterface {
    fun getTheString(): String
}
class MyClass(var theString: String) : MyInterface {
    ...
}

normally when I have a variable in the constructor for a class, it creates a getter and setter for that variable. In MyClass, the methods getTheString() and setTheString(String) exist when not implementing MyInterface.

When MyClass implements MyInterface, I get the error:

Accidental override: The following declarations have the same JVM signature (getTheString()Ljava/lang/String;):

  • public final fun (): String defined in MyClass
  • public abstract fun getTheString(): String defined in MyClass

I also have the error: Class 'MyClass' is not abstract and does not implement abstract member public abstract fun getTheString(): String defined in MyInterface.

So I have a few questions:

  1. Why are 2 getter methods getting generated with the same JVM signature when implementing the interface versus one getter method getting generated without implementing the interface?
  2. Why is it complaining I haven't implemented a getTheString() method when this method is automatically generated by kotlin?
  3. How can I get the getter generated by the variable to become the implementation of the method in the interface?
1
Have you tried @get:JvmName("getTheString_")?EpicPandaForce
@EpicPandaForce that resolves the error on var theString, but does not use the method generated by the variable as the implementation of the method within the interfacebackcab
If you simply want a custom implementation of a property defined in the constructor, check my answer.Louis

1 Answers

2
votes

If the interface is indeed in Kotlin, and you can change it, it should be

interface MyInterface {
    val theString: String
}

in the first place. Java will still see getTheString(), but it's nicer to both implement and use in Kotlin.

Otherwise a good option is

class MyClass(@set:JvmName("setTheString") var _theString: String) : MyInterface {
    override fun getTheString() = _theString
}

Unfortunately, it still has a duplicate getter, and you can't make only the getter private. Or

class MyClass(private var _theString: String) : MyInterface {
    override fun getTheString() = _theString
    fun setTheString(value: String) { 
        _theString = value
    }
}

Note that if the interface is in Java, getTheString() will be visible to Kotlin as a property.

See issues https://youtrack.jetbrains.com/issue/KT-6653 and https://youtrack.jetbrains.com/issue/KT-19444 on the Kotlin bug tracker.