Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Interface's function clashes with Property's getter

Tags:

kotlin

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 } 
like image 555
Eugene Avatar asked Jul 15 '16 11:07

Eugene


2 Answers

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() }  
like image 178
hotkey Avatar answered Sep 25 '22 12:09

hotkey


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   }  } 
like image 23
Lukasz Frankowski Avatar answered Sep 22 '22 12:09

Lukasz Frankowski