Home > other >  What is the difference for each case of this sealed class?
What is the difference for each case of this sealed class?

Time:12-21

While looking at the sample code to use the sealed class, I saw several cases in which the method of using the sealed class was different.

case1 is similar to enum class, but I know that it can create multiple instances.

But what makes case2 different? And I'm wondering what's the difference between inheriting from a normal class(or interface)

case1

The first case is the most common sealed class method in the sample code.

sealed class Parent(
    val t1: String,
    val t2: String,
) {
    data class A(
        val id: String,
        val title: String,
        val num : Int
    ) : Parent(
        t1 = id,
        t2 = title,
    ) { }
    
    data class B(
        val id: String,
        val title: String,
    ) : Parent(
        t1 = id,
        t2 = title,
    ) { }
}

case2

The second case is a case where you are curious about the difference from inheriting a normal class.

sealed class Parent(
    val t1: String,
    open val t2: String,
) { }
data class A(
    val id: String,
    val title: String,
    val num : Int
) : Parent(
    t1 = id,
    t2 = title,
) { }

data class B(
    val id: String,
    val title: String,
) : Parent(
    t1 = id,
    t2 = title,
) { }
open class Parent( // or interface
    val t1: String,
    open val t2: String,
) { }
data class A(
    val id: String,
    val title: String,
    val num : Int
) : Parent(
    t1 = id,
    t2 = title,
) { }

data class B(
    val id: String,
    val title: String,
) : Parent(
    t1 = id,
    t2 = title,
) { }

CodePudding user response:

Case 1:

  • uses nested classes.
  • was the required way to do sealed classes in Kotlin before 1.5.
  • suggests a direct relationship between the nessted and outer class that you might want to carry throughout your code for clarity (like PaymentType.CreditCard, PaymentType.Checking, etc), so can be used as a grouping / organizing strategy
  • requires scoping when declaring fields (val paymentMethod = PaymentMethod.CreditCard(...)) or adding extra imports

Case 2:

  • no more nested classes
  • only possible as of Kotlin 1.5
  • suggests a less direct relationship between the base and derived classes that doesn't require being maintained throughout the code (like Animal, Cat, Dog, etc)
  • Does not require scoping or extra imports (val cat = Cat())

Finally:

And I'm wondering what's the difference between inheriting from a normal class(or interface)

The Kotlin docs are pretty clear on sealed classes and regular classes. The key point for sealed classes being:

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 after a module with the sealed class is compiled. For example, third-party clients can't extend your sealed class in their code. Thus, each instance of a sealed class has a type from a limited set that is known when this class is compiled.

In short: they're enums on crack. (PSA: don't do crack).

  • Related