Table of contents
1.
Introduction
2.
Different types of classes
2.1.
Sealed Class
2.2.
Data Class
2.3.
Enum Class
3.
Examples
3.1.
Instantiating a Sealed Class
3.2.
Sealed Class with 'when' Expression
3.3.
toString() in Kotlin’s Data Class
3.4.
equal() method in Data Class
3.5.
copy() in Data Class
3.6.
‘when’ Expression in Enum Class
3.7.
Kotlin Nested & Inner Classes
4.
FAQs
5.
Key Takeaways
Last Updated: Mar 27, 2024

Kotlin Classes - Sealed, Data, Enum

Author Akshit Pant
0 upvote
Career growth poll
Do you think IIT Guwahati certified course can help you in your career?

Introduction

Before jumping on types of classes, first, let us discuss what a class is?
As we all know that in Kotlin, everything is linked to classes and objects. Moreover, classes are basically 'blueprint' for the creation of objects. To create a class in Kotlin, type the class keyword, which is then followed by the class name.
In this blog we will be talking about: Types of Kotlin Classes - Sealed, Data, Enum, Nested and inner classes.

Different types of classes

Sealed Class

A sealed class confines the hierarchy of classes. The "sealed" keyword can be used before the class name to declare it as a sealed class. Constructors of sealed classes are by default private and cannot be made non-private.
A sealed class is useful when an object has one of the types from a limited set but cannot have any other type.

Syntax of a Sealed class declaration in Kotlin:

sealed class myClass{}

Note: The sealed class's subclasses must be declared in the same file as the sealed class.

Data Class

The Data class is a simple class that holds data and provides typical functions. To declare a class as a data class, use the data keyword.

Syntax of Data class declaration in Kotlin:

data class myClass(val employeeName: String, val employeeId: Int){}

Note: When declaring a data class, keep in mind that it must contain at least one primary constructor with property argument(like var or val).

Enum Class

While coding, sometimes there is a need for a type to have only certain values. The concept of enumeration was invented to do this. A named list of constants is called an enumeration.
An enum has its specialized type in Kotlin, as it does in many other programming languages, signifying that something has many possible values. Kotlin enums are classes, unlike Java enums.

Syntax of Enum class declaration in Kotlin:

enum class myClass{}

Examples

Now, let us take a deep dive into types of Kotlin Classes with some programmatically working examples.

Instantiating a Sealed Class

Just try this set of codes in the compiler-

Code:

sealed class myClass  
fun main()  
{  
var my_Class = myClass()  
}

The compiler's output must be like this:

Output:

Cannot access '<init>': it is protected in 'myClass'
Sealed types cannot be instantiated

The reason is that the Sealed class is implicitly an abstract class that the user cannot instantiate.

Sealed Class with 'when' Expression

It can be observed that Sealed classes are generally used with the 'when' expression, the reason being that the subclasses of the sealed classes have their type. As a result, the 'when' expression in sealed class covers all circumstances, and there is no need to include an else clause.
Here is an example:

Code:

fun main(args: Array<String>) {  
    var circle = Perimeter.Circle(10.0f)  
    var square = Perimeter.Square(10)    
    eval(circle)  
    eval(square)  
    }
    sealed class Perimeter{  
        class Circle(var radius: Float): Perimeter()  
        class Square(var len: Int): Perimeter()  
    }  
    fun eval(e: Perimeter) =  
            when (e) {                  // else statement not req. as all the cases are covered
                is Perimeter.Circle ->println("Perimeter of circle is: ${2*3.14*e.radius}")  
                is Perimeter.Square ->println("Perimeter of square is: ${4*e.len}")
            }


 Output:

Perimeter of circle is: 62.800000000000004
Perimeter of square is: 40

toString() in Kotlin’s Data Class

The data class in Kotlin is solely concerned with data, not with code implementation.
To understand the meaning of this, let us look at a simple code with initially no data class. We are attempting to print the myClass class's reference using its object in the class.

Code:

class myClass(var car: String, var price: Int)  
fun main() {  
val x = myClass("Audi", 25000000)  
println(x)  
}


Output:

myClass@37f8bb67

Here we noticed that, While printing the reference of myClass, it displays the hashcode with the class name(myClass in this case) and does not print the data.
Now, let us re-write the above code using the data class and then try to print the reference again.

Input:

data class myClass(var car: String, var price: Int)  
fun main() {  
val x = myClass("Audi", 25000000)  
println(x)  
}


Output:

myClass(car=Audi, price=25000000)

As we can see, this time, it printed the data. This happened because the data class already contains the toString() function, displaying the object's string representation.

equal() method in Data Class

The equal() method checks that other objects are "equal to" the current object. equals() method returns true if the hashCode is equal, else it returns a false.
Here a simple example of using equal() is given below.

Input:

class useEqual(var item: String, var price: Int)    
fun main() {  
val x = useEqual("house", 10000000)  
val y = useEqual("house", 10000000)  
println(x.equals(y))  
}


Output:

false

Now, Using the same input for data class.

Input:

data class useEqual(var item: String, var price: Int)  
fun main() {  
val x = useEqual("house", 10000000)  
val y = useEqual("house", 10000000)  
println(x.equals(y))  
}


Output:

true

Observe the difference between outputs when we use data class and when not using it.

copy() in Data Class

The copy() function of the data class is used to make a copy of an object. Some or all properties of an object can be changed using the copy() method. Let us see this with an example given below.

Code:

data class copyDone(var item: String, var price: Int)  
fun main() {  
val x = copyDone("house", 10000000)  
println("Data of x is:  $x")  
println()
val z = x.copy()  
println("z copied object from x and is:   $z")
}


Output:

Data of x is:  copyDone(item=house, price=10000000)
z copied object from x and is:   copyDone(item=house, price=10000000)

‘when’ Expression in Enum Class

When enum classes are used with the ‘when’ expression in Kotlin, they provide a significant benefit. The cause of this advantage is because enum classes limit the values a type can take, so when it is used with the ‘when’ expression and the definition for all the constants are provided, then the need for the ‘else’ clause is completely eliminated. In fact, the compiler will issue a warning if one tries to do so.
Let us see an example covering all the possible queries about using the ‘when’ expression in the enum class.

Code:

enum class myCalendar{
    Jan,
    Feb,
    Mar,
    Apr,
    May,
    Jun,
    Jul,
    Aug,
    Sep,
    Oct,
    Nov,
    Dec;
}  
fun main(){
    when(myCalendar.Jun){  // no need of 'else' clause
        myCalendar.Jan -> println("Coding Ninjas")
        myCalendar.Feb -> println("Blog Writing")
        myCalendar.Mar -> println("Sunny day")
        myCalendar.Apr -> println("Rainy season")
        myCalendar.May -> println("Warm weather")
        myCalendar.Jun -> println("It's my birthday!")
        myCalendar.Jul -> println("Happy Journey!")
        myCalendar.Aug -> println("Save drive")
        myCalendar.Sep -> println("Call me asap")
        myCalendar.Oct -> println("Hello!")
        myCalendar.Nov -> println("Bye Bye")
        myCalendar.Dec -> println("See Ya!")
    }
}


Output:

It's my birthday!

Kotlin Nested & Inner Classes

Note down the fact that classes can be nested easily in other classes. Not just this, Interfaces with nesting can also be used. It is possible to mix and match classes and interfaces in any way one wants: Interfaces can be nested within classes, classes within interfaces, and interfaces within interfaces.

Syntax:

class myOuterClass {
    //.........codes
   
    class myNestedClass {
        //..........codes   
    }
}


Inner Class: The members of an outer class can be accessed by a nested class defined as inner. Inner classes carry a reference to an item of an outside class.

Let us learn more about it with this example.

Code:

class myOuterClass{
    val x = " This is first class(outside nested one) "
    inner class myInnerClass{
        fun funCall() = x
    }
}
fun main(args: Array<String>) {
    val outerVarX = myOuterClass()
    println("Use of outer object: ${outerVarX.myInnerClass().funCall()}")
    val innerVarX = myOuterClass().myInnerClass()
    println("Use of inner object: ${innerVarX.funCall()}")
}

 

Output:

Use of outer object:  This is first class(outside nested one)
Use of inner object:  This is first class(outside nested one)

FAQs

  1. What are the requirements for the data class?
    FirstThe primary constructor requires at least one parameter. Second, For all the parameters, val or var must be used. Third, It is not possible to have data class as abstract, inner, open, or sealed. Fourth, Data classes are only allowed to implement interfaces.
     
  2. For data classes, which functions are automatically derived by the compiler?
    These are the following functions:
    equals()hashCode()copy()toString().
     
  3. Why do we use Companion Object in a class in Kotlin?
    The static keyword is used in some languages, such as Java, to declare class members and utilize them without constructing an object, i.e., by merely calling them by their class name. There is no such thing as a "static" keyword in Kotlin. As a result, we employ companion objects to achieve the functionality of static member functions.

Key Takeaways

In this article, we learned about  Kotlin Classes and their type: Sealed, data, Enum. We also infer from this article a basic idea about how to initialize and use them with their properties and functionalities.
Head over to our Android Development Course on the Coding Ninjas Website to dive deep into Android Development and build future applications. 
We hope this article has helped you enhance your knowledge of  Kotlin Classes. If you want to learn more, check out our article on environment setup and Competitive Programming articles. Do upvote this article to help other ninjas grow.

Live masterclass