从Kotlin的密封类扩展数据类
我有一组数据类共享一些共同的领域,所以理想情况下,我想声明这些超类型(在这个例子中的消息),并能够编写的功能,操作超类型,如果他们需要访问这些常见字段(在这个例子中是messageId)。
fun operate(m: Message) { use(m.messageId) }
我试图通过从密封类扩展我的数据类来实现这一点。
数据类可以扩展密封类,但不是我不知道如何/如果他们可以接受“超类型”密封类所需的参数。
-
从一个密封的类扩展一个普通的类编译就好了。
sealed class Message(val messageId: String) class Track(val event: String, messageId: String): Message(messageId)
-
但是,将其更改为数据类不会编译(“数据类主构造函数必须只有属性(val / var)参数”)。
sealed class Message(val messageId: String) data class Track(val event: String, messageId: String): Message(messageId)
-
声明参数作为属性也不会编译(“'messageId'隐藏超类型'消息'的成员,并需要'覆盖'修饰符'”)。
sealed class Message(val messageId: String) data class Track(val event: String, val messageId: String): Message(messageId)
-
打开超类型属性,并在每个基类中重写它编译罚款:
sealed class Message(open val messageId: String) data class Track(val event: String, override val messageId: String): Message(messageId)
理想情况下,我想要接近选项2 – 它允许我结合两全其美。
否则,看起来我的选择是用选项1来滚动我自己的数据类功能(复制,散列码,等于等等),或者用选项4打开超类型属性来折中妥协。
选项3和4将导致该类持有messageId
两次。 一旦进入新班级,一次进入超班。
解决方案是声明但不是在超类中定义变量:
sealed class Message { abstract val messageId: String } data class Track(val event: String, override val messageId: String): Message()
这将使MessageId在Message
可用,但是将存储委托给实现它的任何东西。