Hello all! I am looking for a way to extend the i...
# getting-started
b
Hello all! I am looking for a way to extend the interface of an existing class without modifying the class itself. I was reading about receivers thinking there might be a way to achieve the desired result, but I am having trouble wrapping my head around the concept. Concrete example in thread…
I have a few room database entities
Copy code
@Entity(...)
data class FooEntity()

@Entity(...)
data class BarEntity()
I would like each entity to implement some interface without polluting the entity class itself
Copy code
interface Writeable {
  fun write()
}
I am currently creating a wrapper object that implements the interface for each entity
Copy code
class FooWriteable(private val foo: Foo): Writeable

class BarWriteable(private val bar: Bar): Writeable
Combing through the discussion here: https://discuss.kotlinlang.org/t/implementing-an-interface-for-an-existing-type/20967/11 It mentions receivers as a possible solution. Currently having trouble fully understanding. Am I heading down the right path with receivers? Could someone possibly at least point me in the right direction? Thanks!
j
Swift supports this and its beautiful
☝️ 1
Wait, its seems like context receivers could allow to do this (not sure at all about that, I'll let context receiver experts talk about this)
👍 1
y
Is the interface set in stone? Or is it your own custom thing? Basically, you can change the interface to be:
Copy code
interface Writeable<T> {
  fun T.write()
}
And have implementations of it defined:
Copy code
object FooWriteable: Writeable<Foo> {
  fun Foo.write() = TODO()
}
and then any function that takes a Writeable should instead be defined like so:
Copy code
context(Writeable<W>)
fun <W> myCustomWrite(writeable: W) {
  writeable.write()
}
And as you can see, you can't tell the difference on the callsite.
b
Thank you! I guess the part I am still missing is how to convert my entity pojos.
Copy code
val foos = fooRepository.getFoos()
val bars = barRepository.getBars()

val writeables = foos + bars
myCustomWrite(writables)
y
No need to convert, you just do
with(FooWriteable)
Edit: oh in this case you might run into issues because Foo and bar have different types. Maybe
myCustomWrite
could just take 2 different list
b
That is when I tell you I don’t just have foo and bar, I have 12 different types
y
Do they all need to be placed together into lists? If so, I'm afraid wrapping might be the best solution for now. However, soon enough, we'll have union types, and then maybe you could write this in a nicer way by having a list of Union of the 12 types, and having a
UnionWriteable
that implements writeable for all those types