WestCoastProjects
WestCoastProjects

Reputation: 63032

How to specify a typeclass for data classes in Kotlin

In scala the parent class backing the case class is product : so we can use that for polymorphism across case classees. How can a similar goal be achieved for data classes in kotlin?

For the yaml parser below I would need a replacement for dataclass that represents a reasonable parent class of all data classes.

enter image description here

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)
    }
}

Upvotes: 2

Views: 1209

Answers (1)

Mikhail Spitsin
Mikhail Spitsin

Reputation: 2608

If I understood you correctly, I don't think it is possible in Kotlin. Data classes are just ordinary classes. Thus, you can inherit it from any open/abstract class, interface or sealed class. In the meantime, there is no way to inherit from data class, for instance, to force all children to be data class. And there is no data class-specific inheritance because as I mentioned data class is just an ordinary class with a predefined and pre-generated bunch of methods.

I think it is also worth thinking about it: Do you really need to identify every passed class as a data class at compile-time, and why you really need it?

If for instance, you want to apply any kind of polymorphism, then all you can use is just equals/hashCode/toString, because componenN and copy functions are just generated and have no base functions which they could override.

Since every class can implement those 3 methods. All you can do is to force implement them. For instance:

interface DataClass {
    override fun equals(other: Any?): Boolean
    override fun hashCode(): Int
    override fun toString(): String
}

data class Impl(val t: Int) : DataClass

In that case there is a high possibility that implementation will be forced to be data class, or it will be forced to provide all 3 needed methods. But this is hack rather than actual solution and you will not be able to apply that for 3rd-party-classes, since you will not be able to mark them with this interface.

In summary: I would recommend to think do you really need to know, is the clz from your example data class, or it can be anything. If yes, then you may consider to use reflection.

Please, see this: Is there a way to identify a Kotlin data class from a regular Kotlin class?

Upvotes: 3

Related Questions