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