Introduction
Kotlin is a new generation language officially for Android developement. Well --- we are taking about the sealed classes. According to official docs "Sealed classes are used for representing restricted class hierarchies wherein the object or the value can have value only among one of the types, thus fixing your type hierarchies. Sealed classes are commonly used in cases, where you know what a given value to be only among a given set of options".
As the name implies, the sealed classes are restricted classes or bound class heirarchies. Sealed classes ensure type-safety by restricting the types to be matched at compile-time rather than at runtime.
How to define a Sealed Class?
- By default a sealed class is abstract, therefore it cannot be instantiated.
- Constructor by default is private.
- To define a sealed class, just precede the class modifier with the sealed keyword.
A typical structure of sealed class is as follows:
- sealed class Demo
- fun main(args: Array)
- {
- var d = Demo() //compiler error Demo can not instantiated
- }
- sealed class Demo {
- class A : Demo() {
- fun display()
- {
- println("Subclass A of sealed class Demo")
- }
- }
- class B : Demo() {
- fun display()
- {
- println("Subclass B of sealed class Demo")
- }
- }
- }
- fun main()
- {
- val obj = Demo.B()
- obj.display()
- val obj1 = Demo.A()
- obj1.display()
- }
Subclass B of sealed class Demo
Subclass A of sealed class Demo
Difference between Enums and Sealed classes
Sealed classes in Kotlin can be thought of as enums on steroids. Sealed classes allow us to create instances with different types, unlike Enums which restrict us to use the same type for all enum constants.
The following is not possible in enum classes.
The enums can take single types of constants. This situation is overcome by Sealed classes which holds the different type of constants.
The following is not possible in enum classes.
- enum class Months(string: String){
- January("Jan"), February(2),
- }
- sealed class Months {
- class January(var shortHand: String) : Months()
- class February(var number: Int) : Months()
- class March(var shortHand: String, var number: Int) : Months()
- }
Sealed classes with when
Sealed classes are widely used with the when statements as the choices become the subclasses and their type acts as a case.
Let's see how when is used with sealed classes. We have a sealed class with named as shape with three different subclasses. Now this subclass became the choice in when.
Let's see how when is used with sealed classes. We have a sealed class with named as shape with three different subclasses. Now this subclass became the choice in when.
Example 1
Now convert the above code with "when".
Let's call the above method in the main function.
Output
- sealed class Shape{
- class Circle(var radius: Float): Shape()
- class Square(var length: Int): Shape()
- class Rectangle(var length: Int, var breadth: Int): Shape()
- }
- fun eval(e: Shape) =
- when (e) {
- is Shape.Circle -> println("Circle area is ${3.14*e.radius*e.radius}")
- is Shape.Square -> println("Square area is ${e.length*e.length}")
- is Shape.Rectangle -> println("Rectagle area is ${e.length*e.breadth}")
- }
- fun main(args: Array<String>) {
- var circle = Shape.Circle(4.5f)
- var square = Shape.Square(4)
- var rectangle = Shape.Rectangle(4,5)
- eval(circle)
- eval(square)
- eval(rectangle)
- //eval(x) //compile-time error.
- }
Circle area is 63.585
Square area is 16
Rectangle area is 20
Example 2
Let's see another example to demonstrate when statment with sealed class.
Output
- // A sealed class with a string property
- sealed class Fruit
- (val x: String)
- {
- // Two subclasses of sealed class defined within
- class Apple : Fruit("Apple")
- class Mango : Fruit("Mango")
- }
- // A subclass defined outside the sealed class
- class Pomegranate: Fruit("Pomegranate")
- // A function to take in an object of type Fruit
- // And to display an appropriate message depending on the type of Fruit
- fun display(fruit: Fruit){
- when(fruit)
- {
- is Fruit.Apple -> println("${fruit.x} is good for iron")
- is Fruit.Mango -> println("${fruit.x} is delicious")
- is Pomegranate -> println("${fruit.x} is good for vitamin d")
- }
- }
- fun main()
- {
- // Objects of different subclasses created
- val obj = Fruit.Apple()
- val obj1 = Fruit.Mango()
- val obj2 = Pomegranate()
- // Function called with different objects
- display(obj)
- display(obj1)
- display(obj2)
- }
Apple is good for iron.
Mango is delicious.
Pomegranate is good for vitamin d.

Join the conversation! Your thoughts help the community grow.