在scala
中,支持case class
的父类是product
:因此我们可以将其用于跨case classe
es的多态性。对于data class
中的kotlin
,如何实现类似的目标?
对于下面的yaml
解析器,我需要替换dataclass
,它代表所有data classes
的合理父类。
inline fun <reified T: dataclass> loadFromFileDC(path: Path): T = loadFromFile(path, T::class)
fun <T: dataclass> loadFromFile(path: Path, cls: KClass<T>) = {
val mapper = ObjectMapper(YAMLFactory()) // Enable YAML parsing
mapper.registerModule(KotlinModule()) // Enable Kotlin support
Files.newBufferedReader(path).use {
mapper.readValue(it, cls.java)
}
}
如果我对您的理解正确,我认为在Kotlin中是不可能的。数据类只是普通类。因此,您可以从任何打开/抽象类,接口或密封类继承它。同时,没有办法从数据类继承,例如,强制所有子代成为数据类。而且没有特定于数据类的继承,因为正如我提到的,数据类只是具有预定义和预先生成的方法的普通类。
我认为也值得考虑:您是否真的需要在编译时将每个传递的类标识为数据类,为什么真正需要它?
例如,如果您想应用任何种类的多态性,那么您只能使用equals
/hashCode
/ toString
,因为componenN
和copy
函数只是生成的,没有基数他们可以覆盖的功能。
由于每个类can都实现了这3种方法。您所能做的就是强制实施它们。例如:
interface DataClass {
override fun equals(other: Any?): Boolean
override fun hashCode(): Int
override fun toString(): String
}
data class Impl(val t: Int) : DataClass
在那种情况下,很可能将实现强制为数据类,或者将强制提供所有3种所需的方法。但这是hack,而不是实际的解决方案,您将无法将其应用于3rd-party类,因为您将无法使用此界面对其进行标记。
总结:我建议您考虑一下您真正需要知道的是示例clz
中的data class
,还是可以是任何东西。如果是,那么您可以考虑使用反射。
请参阅:Is there a way to identify a Kotlin data class from a regular Kotlin class?