2

With given kotlin code :

sealed class Event(val id:String= UUID.randomUUID().toString(), val timestamp:Instant = Instant.now())
data class BarEvent(val additionalInfo:String):Event()
object FooEvent:Event()
// data class CorrectFooEvent():Event() // invalid kotlin

fun main(args: Array<String>) {
    val b1 = BarEvent("b1")
    val f1 = FooEvent
    Thread.sleep(1000)
    val b2 = BarEvent("b2")
    val f2 = FooEvent

    println("${b1.id} ${b1.timestamp} $b1")
    println("${f1.id} ${f1.timestamp} $f1")
    println("${b2.id} ${b2.timestamp} $b2")
    println("${f2.id} ${f2.timestamp} $f2")
}

There is no issue with BarEvent.

But as FooEvent has no more parameter than the ones in Event, I would like it to have empty constructor. It's not authorized for data class, so I made it an object. But object is singleton, so it doesn't behave as an instanciated event.

The only workaround that I see (keeping the class as a data class) is something like :

sealed class Event(open val id:String= UUID.randomUUID().toString(), open val timestamp:Instant = Instant.now())
data class FooEvent(override val id:String= UUID.randomUUID().toString(), override val timestamp:Instant = Instant.now()):Event()

But it's not very elegant.

1 Answer 1

3

Just change FooEvent to a normal class, and add (or generate them using your IDE) toString(), hashCode() and equals(Object) if needed:

class FooEvent: Event() {
    override hashCode() = ...
    override equals(other: Object) {
        ...
    }
    override toString() = ...
}

To make the event a data class, simply add an unused property to it. Not pretty, but as short as it can be in Kotlin at the moment:

data class FooEvent(val dummy: Unit = Unit) : Event()

There seems to be no intention to remove this limitation soon:

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks but it also means I lost copy and destructuring functionality of "data class". That why I said "keeping the class as a data class".
Their decision seems to make sense at 1.0 time. No destructuring, no inheritance of data class. But now, it'a a bit weird... Thanks anyway.
Your answer before edit was right. I should not use the data class in this case. From data class documentation, inherited field are not included in data class feature. Quoting the doc "The compiler automatically derives the following members from all properties declared in the primary constructor:". (Thanks to kotlinglang slack community for pointing it out)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.