I want to dynamically implement an interface by extending an existing class as an anonymous object. This anonymous object captures a method parameter to implement the interface method:
fun myFunc(someObj: SomeObj, update: Boolean) = object : SomeObj(/*copy some values from someObj*/), SomeInterface {
override fun doUpdate() = update
}
This implementation captures the update
method parameter and adds it as a synthetic $update
field into the anonymous object. I need to annotate this field as my serialization framework includes the $update
field when its not marked as @Transient
.
Another approach by delegation suffers from the same issue:
fun myFunc(someObj: SomeObj, update: Boolean) {
val someInterfaceImpl = object : SomeInterface {
override fun doUpdate() = update
}
return object : SomeObj(/*copy some values from someObj*/), SomeInterface by someInterfaceImpl
}
I cannnot annotate someInterfaceImpl
in any place with @delegate:Transient
or @Transient
.
In essence:
I am required to do this by annotations as the framework does not offer any other way to exclude fields, not even by names.
Furthermore I am not talking about delegated properties but delegated interfaces.
Create a named class:
fun myFunc(someObj: SomeObj, update: Boolean): SomeObj {
class SomeObjSubclass(someObj: SomeObj, @Transient val update: Boolean):
SomeObj(someObj.prop1, someObj.prop2, /* and so on*/), SomeInterface {
override fun doUpdate() = update
}
return SomeObjSubclass(someObj, update)
}
Notice that myFunc
is now merely a wrapper for SomeObj
. Depending on your design, you could just make myFunc
the SomeObj
subclass instead:
class MyFunc(someObj: SomeObj, @Transient val update: Boolean):
SomeObj(someObj.prop1, someObj.prop2, /* and so on*/), SomeInterface {
override fun doUpdate() = update
}
Callers would call MyFunc(...)
as if it were a function, and they would receive something assignable to SomeObj
, just like before.
You can also add a secondary constructor to SomeObj
that takes a SomeObj
, and copy the properties there
constructor(someObj: SomeObj): this(
someObj.prop1, someObj.prop2, /* and so on */
)
Then the declaration of MyFunc
can just be:
class MyFunc(someObj: SomeObj, @Transient val update: Boolean):
SomeObj(someObj), SomeInterface {
override fun doUpdate() = update
}