I am learning Kotlin. My code is as follows:
interface BaseLogicDecoupler<A : BaseViewNotifier, B : BaseScreenRouter> {
var notifier: A?
var router: B?
fun attachNotifier(notifier: A?) {
this.notifier = notifier
}
fun detachNotifier() {
notifier = null;
}
fun attachRouter(router: B?) {
this.router = router
}
fun detachRouter() {
router = null;
}
}
But when I change it and try to provide an accessor for property like following :
var notifier: A?
get() = notifier
It doesn't compile with error saying : Property in interface cannot have a backing field.
From the doc here, kotlin interfaces can provide implementation and can have properties with accessors. Why does the compilation fail?
I am unable to understand the error. What does it say? Can anyone explain in simple terms?
This is an unexpected corner case, kudos to you for finding it.
Let me briefly explain it what goes on. I will use a stripped interface A
and class B
for the sake of simplicity:
interface A {
var notifier: Int
}
Normally a var
property in a class includes 3 components: a private backing field
to store its value, a setter
method to write to it and a getter
method to read it. But an interface cannot have a field (because live is pain and some math does not add up if it does), so a var
property in an interface includes only 2 components: a setter
and a getter
.
As I outlined above, our interface A
has declared 2 methods: a setter
and a getter
, both without implementations. Let's add some implementations to it:
interface A2 {
var notifier: Int
get() {return 1}
set(v) {}
}
So far, so good. Two open
methods with implementations, non of them uses any fields. But what if only one of the implementations is declared?
interface A3 {
var notifier: Int //ERROR: Property in an interface cannot have a backing field
get() {return 1}
//set(v) {}
}
It turns out that if you specify only a getter
, Kotlin also generates a (default) setter
for the property. In other words, A3
is similar to A4
here:
interface A4 {
var notifier: Int
get() {return 1}
set(v) {field = v} //Obviously an error
}
This may be a bug or an intended behaviour. Here is the issue ticket: https://youtrack.jetbrains.com/issue/KT-15193
Possible workarounds:
A2
abstract class
instead of an interfaceIf you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With