Home > Software design >  Kotlin sealed class
Kotlin sealed class

Time:09-21

I have below class, I would like to make this class a sealed class. Can you please help me as I am new to Kotlin.

   @JsonTypeInfo(
        use = JsonTypeInfo.Id.NAME,
        include = JsonTypeInfo.As.PROPERTY,
        property = "type")
    @JsonSubTypes(
        JsonSubTypes.Type(value = A:class, name = "PIZZA"),
        JsonSubTypes.Type(value = B::class, name = "DONUT"),
        JsonSubTypes.Type(value = C::class, name = "ICECREAM"),
        JsonSubTypes.Type(value = D::class, name = "CHOCOLATE"),
    )
    open class food (var type: foodType, var quantity : String) {
        open val taste : String=""
    }

How to make this a sealed class perhaps a subclass of a sealed class, and how to instantiate it?

The foodType is enum class

enum class foodType {
    PIZZA,
    DONUT,
    ICECREAM,
    CHOCOLATE
}

I have the following based on the other post, but I am confused on passing the right parameters. Can someone help me understand what parameter I need to pass??

sealed class food (var type: foodType, var quantity: String) {
class favFood(taste: String): food(?, ?)

}

CodePudding user response:

What is a sealed class ?

When you create a sealed class, you only allow the implementations you created, just like for an enum (Only the constants you added are allowed). Once the module is compiled, you can't add any additional implementation anymore (in opposite to an open class).

Here is the link to the Kotlin documentation about sealed classes : https://kotlinlang.org/docs/sealed-classes.html

Sealed classes are interesting when you want to restrict the implementations to a strict proposition. It can be the case with your use case, to restrict the jsonSubTypes you allow (others wouldn't be mapped).

How to transform an open class to a sealed class ?

So to transform your open class to a sealed class, you generally just need to change the keyword open to sealed. However, you also need to understand how the inheritance mechanism work with sealed classes.

For your example

With JsonSubType, you just need to map the property type to an implementation of your sealed class using a constant of your choice.

Also, you have to provide the values to your sealed class' properties when you extend it, so when you create your implementations.

In the next example, you can find how to give a value to your sealed class properties and what will be the result when you map it to json using JSonSubType :

@JsonTypeInfo(
    use = JsonTypeInfo.Id.NAME,
    include = JsonTypeInfo.As.PROPERTY,
    property = "type")
@JsonSubTypes(
    JsonSubTypes.Type(value = Pizza::class, name = "Pizza"),
    JsonSubTypes.Type(value = Donut::class, name = "DonutDesert"), // As you can see, name is a value you give, not always need to be the class name
    JsonSubTypes.Type(value = IceCream::class, name = "IceCream")
)
sealed class Food(val taste: String)

class Pizza(val size: PizzaSize, taste: String) : Food(taste) {
    enum class PizzaSize {
        SMALL,
        MEDIUM,
        LARGE
    }
}
class Donut(val glaze: String, taste: String) : Food(taste)
class IceCream(val servings: Int, taste: String) : Food(taste)

class Basket(foods: List<Food>)

/* If you map a Basket to JSON, it will give you this : 
{ foods: [
    { "type": "Pizza", "size": "MEDIUM", "taste": "Hawaii" }, 
    { "type": "DonutDesert", "glaze": "Sugar & Marshmallows", "taste" : "chocolate"}, 
    { "type": "IceCream", "servings": 3, "taste": "Strawberry" }
]}
*/


  • Related