Eugene
Eugene

Reputation: 60184

Interface's function clashes with Property's getter

An interface's function name clashes with a property's getter name intentionally, but it's prohibited by the compiler because of accidental override problem. Is it possible to instruct the compiler this is intentional?

interface A {
  fun getFoo()
}

class B: A {
  val foo
}

Upvotes: 31

Views: 4922

Answers (2)

Lukasz Frankowski
Lukasz Frankowski

Reputation: 3175

The Kotlin-idiomatic approach from the answer above is OK until we stick with Kotlin, but if these interface are defined in Java it's not applicable. There're a plenty of propositions reported in KT-6653 but none of them is currently implemented. I'm currently writing some app which is partially in Java and partially in Kotlin and this problem completely kills "Kotlin-Java interoperability" concept.

The only solution I've found to workaround it is the following one:

public interface A {
  String getFoo();
}
class B(private val _foo: String): A {

  override fun getFoo(): String = _foo

}

It's also possible to extend this class with setter:

class B(private var _foo: String): A {

  override fun getFoo(): String = _foo

  fun setFoo(foo: String) {
    _foo = foo
  }

}

Upvotes: 6

hotkey
hotkey

Reputation: 147951

This feature seems not to be implemented in any way.

@AndreyBreslav's comment on a similar question:

You can not override Java methods with Kotlin properties at the moment. It would be nice if we could support it, but we don't know how to do it consistently for mixed hierarchies


This does not solve your problem but at least makes the code compile: you can change JVM name of the getter with the @JvmName annotation:

interface A {
    fun getFoo(): SomeType
}

class B: A {
    override fun getFoo() = foo

    val foo: SomeType = someValue()
        @JvmName("getFoo_") get() = field
}

Also, consider changing to a more idiomatic approach: define the val-property in your interface, so that you can override it in the implementations:

interface A {
    val foo: SomeType
}

class B : A {
    override val foo: SomeType = someValue()
}

class C : A {
    override val foo: SomeType
        get() = someCustomGetter()
} 

Upvotes: 29

Related Questions