Home > database >  Can sealed class subclasses call a inherited method and return the subclass instance?
Can sealed class subclasses call a inherited method and return the subclass instance?

Time:02-04

How can I share sealed class methods by the subclasses and return the typeof "this"? I don't want to cast every time I call it, but implement it in the method signature if possible. Is there a simple way?

sealed class Base {
    fun customCopy() = when (this) {
        is X -> copy()
        is Y -> copy()
    }
}
data class X(val x: String) : Base()
data class Y(val y: String) : Base()

fun main() {
    val x1 = X("x")
    val x2: X = x1.customCopy() // Required X, but found Base
}

Above, I want x1.customCopy() to return X instead of Base.

CodePudding user response:

You have to use generics to implement it.

Something like this:

fun <T: Base> customCopy():T = when (this) {
    is X -> copy()
    is Y -> copy() 
} as T

Or you can use extension function which provides more type safety:

fun <T: Base> T.extCopy():T = when(this) {
    is X -> copy()
    is Y -> copy()
    else -> throw InvalidParameterException()
} as T

CodePudding user response:

That doesn't really make any sense, might be more clear for you if you add the explicit return type of customCopy() instead of inferring it.

    fun customCopy(): Base = when (this) {
        is X -> copy()
        is Y -> copy()
    }

customCopy has to return Base, otherwise the second code path can't compile. If you remove all non-X returning code paths (eg. by throwing an exception) the inferred type will become X instead.

It's quite unclear what problem you are really asking to solve, because your example should just call x1.copy() directly.

  • Related