[英]Extending data class from a sealed class in Kotlin
I have a set of data classes that share some common fields, So ideally I'd like to declare those in a supertype (Message in this example), and be able to write functions that operate on the supertype if they need access to these common fields (messageId in this example).我有一组共享一些公共字段的数据类,因此理想情况下,我想在超类型(本示例中为 Message)中声明它们,并且如果需要访问这些公共字段,则能够编写对超类型进行操作的函数字段(本例中的 messageId)。
fun operate(m: Message) {
use(m.messageId)
}
I tried to accomplish this by extending my data classes from a sealed class.我试图通过从密封类扩展我的数据类来实现这一点。
Data classes may extend sealed classes, but not I'm not sure how/if they can accept arguments required by the "supertype" sealed class.数据类可以扩展密封类,但我不确定它们如何/是否可以接受“超类型”密封类所需的参数。
Extending a regular class from a sealed class compiles just fine.从密封类扩展常规类编译就好了。
sealed class Message(val messageId: String) class Track(val event: String, messageId: String): Message(messageId)
However, changing it to a data class doesn't compile ("Data class primary constructor must have only property (val/var) parameters.").但是,将其更改为数据类不会编译(“数据类主构造函数必须只有属性(val/var)参数。”)。
sealed class Message(val messageId: String) data class Track(val event: String, messageId: String): Message(messageId)
Declaring the parameter as a property also doesn't compile ("'messageId' hides member of supertype 'Message' and needs 'override' modifier'").将参数声明为属性也不会编译(“'messageId' 隐藏了超类型 'Message' 的成员并且需要 'override' 修饰符'”)。
sealed class Message(val messageId: String) data class Track(val event: String, val messageId: String): Message(messageId)
Opening the supertype property and overriding it in each of the base classes compiles fine:打开超类型属性并在每个基类中覆盖它可以很好地编译:
sealed class Message(open val messageId: String) data class Track(val event: String, override val messageId: String): Message(messageId)
Ideally I would like something close to Option 2 - it allows me to combine the best of both worlds.理想情况下,我想要接近选项 2 的东西——它让我能够结合两全其美。
Otherwise, it seems my options are either handrolling my own data class functionality (copy, hashcode, equals etc) with option 1, or live with a compromise by opening up up the supertype properties with option 4.否则,我的选择似乎是使用选项 1 手动滚动我自己的数据类功能(复制、哈希码、等于等),或者通过使用选项 4 打开超类型属性来妥协。
Options 3 and 4 would result in the class holding messageId
twice.选项 3 和 4 将导致该类持有两次
messageId
。 Once in the new class and once in its superclass.一次在新类中,一次在其超类中。
The solution is to declare but not define the variable in the superclass:解决方法是在超类中声明但不定义变量:
sealed class Message {
abstract val messageId: String
}
data class Track(val event: String, override val messageId: String): Message()
This will make the messageId available on Message
, but delegates the storage to whatever implements it.这将使 messageId 在
Message
可用,但将存储委托给任何实现它的人。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.