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