Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sealed data class in Kotlin

Tags:

kotlin

I have the following sealed classes

sealed class DownloadWallpaper : Result() {
    data class Progress(val hd: Boolean = false, ...) : DownloadWallpaper() 
    data class Success(val hd: Boolean = false, ...) : DownloadWallpaper()
    data class Error(val hd: Boolean = false, ...) : DownloadWallpaper()
}

And I am trying to do the following.

//obs is of type Observable<Detail.Result.DownloadWallpaper> 
obs.map{ it.copy(hd = true) }

But I cant, for two reasons since DownloadWallpaper isn't a data class. There's not .copy() method. How can I tell Kotlin that all classes in this seal class are in fact data classes?

Secondly, DownloadWallpaper it self doesn't have an 'hd' field. I could cast this using when How can fix this elegantly? This solution is quite ugly:

when (it) {
           is Detail.Result.DownloadWallpaper.Success -> it.copy(hd = true)
           is Detail.Result.DownloadWallpaper.Progress -> it.copy(hd = true)
           is Detail.Result.DownloadWallpaper.Error -> it.copy(hd = true)
 }
like image 936
frankelot Avatar asked Dec 02 '17 19:12

frankelot


People also ask

What's a sealed class in Kotlin?

A sealed class defines a set of subclasses within it. It is used when it is known in advance that a type will conform to one of the subclass types. Sealed classes ensure type safety by restricting the types to be matched at compile-time rather than at runtime.

Why should I use sealed class Kotlin?

Sealed classes and interfaces represent restricted class hierarchies that provide more control over inheritance. All direct subclasses of a sealed class are known at compile time. No other subclasses may appear outside a module within which the sealed class is defined.

Can you have sealed interface in Kotlin?

Sealed Interface. ✔ ️Sealed interfaces were just introduced in Kotlin 1.5 and are a very powerful new feature. But with great power comes great responsibility, so we need to learn when to use and when to not use this newly achieved power.

What is sealed class with example?

A sealed class, in C#, is a class that cannot be inherited by any class but can be instantiated. The design intent of a sealed class is to indicate that the class is specialized and there is no need to extend it to provide any additional functionality through inheritance to override its behavior.


1 Answers

By adding a few abstract methods to your sealed class I was able to access copy methods without explicit type check. See for yourself:

sealed class DownloadWallpaper {
    abstract val hd: Boolean
    abstract fun copy(hd: Boolean): DownloadWallpaper
}

data class Progress(override val hd: Boolean = false, val a: Any) : DownloadWallpaper() {
    override fun copy(hd: Boolean) = copy(hd = hd, a = a)
}
data class Success(override val hd: Boolean = false, val s: String) : DownloadWallpaper() {
    override fun copy(hd: Boolean) = copy(hd = hd, s = s)
}
data class Error(override val hd: Boolean = false, val c: Int) : DownloadWallpaper() {
    override fun copy(hd: Boolean) = copy(hd = hd, c = c)
}

fun main() {
    val dw: DownloadWallpaper = Progress()
    val newDw = dw.copy(hd = false)
    val newDwSameHd = dw.copy(hd = dw.hd)
}
like image 90
SimY4 Avatar answered Sep 21 '22 15:09

SimY4