Kotlin sealed classes provide a powerful mechanism for defining restricted hierarchies where a value can only have one of the types from a limited set. This article dives into sealed classes, their purpose, usage, benefits, and a real-world example showcasing their functionality.
Understanding Sealed Classes
Sealed classes in Kotlin are used to represent restricted hierarchies where a value can have a limited number of types. Unlike regular classes, sealed classes can have a predefined set of subclasses within the same file, and they are often used to model complex data structures with a finite number of possibilities.
Example Problem
Let’s consider a scenario where we have different shapes such as Circle, Square, and Rectangle. We want to calculate the area of each shape, but we also want to handle any new shapes added in the future without introducing bugs.
Creating a Sealed Class
To address the above problem, we’ll create a sealed class Shape
with subclasses representing different shapes.
sealed class Shape
class Circle(val radius: Double) : Shape()
class Square(val sideLength: Double) : Shape()
class Rectangle(val length: Double, val width: Double) : Shape()
fun calculateArea(shape: Shape): Double {
return when (shape) {
is Circle -> Math.PI * shape.radius * shape.radius
is Square -> shape.sideLength * shape.sideLength
is Rectangle -> shape.length * shape.width
}
}
In this example:
Shape
is a sealed class representing different shapes.Circle
,Square
, andRectangle
are subclasses ofShape
, each representing a specific shape.
Let’s use the sealed class Shape
in a real-world scenario where we calculate the areas of different shapes.
fun main() {
val circle = Circle(5.0)
val square = Square(4.0)
val rectangle = Rectangle(3.0, 6.0)
println("Area of Circle: ${calculateArea(circle)}")
println("Area of Square: ${calculateArea(square)}")
println("Area of Rectangle: ${calculateArea(rectangle)}")
}
Output:
Area of Circle: 78.53981633974483
Area of Square: 16.0
Area of Rectangle: 18.0
Explanation
- We create instances of
Circle
,Square
, andRectangle
, passing relevant parameters. - The
calculateArea
function calculates the area based on the type of shape using awhen
expression.
Example: Payment Methods Management
Imagine you’re developing a payment processing system that supports multiple payment methods such as Credit Card, PayPal, and Bank Transfer. Each payment method has its specific details and processing logic. Sealed classes can help model these payment methods effectively.
Sealed Class: PaymentMethod
Let’s create a sealed class PaymentMethod
with subclasses representing different payment methods.
sealed class PaymentMethod {
abstract fun processPayment(amount: Double): Boolean
}
class CreditCard(val cardNumber: String, val cvv: String) : PaymentMethod() {
override fun processPayment(amount: Double): Boolean {
// Process credit card payment logic
println("Processing credit card payment of $amount")
return true
}
}
class PayPal(val email: String, val password: String) : PaymentMethod() {
override fun processPayment(amount: Double): Boolean {
// Process PayPal payment logic
println("Processing PayPal payment of $amount")
return true
}
}
class BankTransfer(val accountNumber: String) : PaymentMethod() {
override fun processPayment(amount: Double): Boolean {
// Process bank transfer payment logic
println("Processing bank transfer payment of $amount")
return true
}
}
In this example:
PaymentMethod
is a sealed class representing different payment methods.CreditCard
,PayPal
, andBankTransfer
are subclasses ofPaymentMethod
, each representing a specific payment method.
Payment Processing
Let’s use the sealed class PaymentMethod
to process payments in our system.
fun main() {
val creditCard = CreditCard("1234 5678 9012 3456", "123")
val payPal = PayPal("[email protected]", "password")
val bankTransfer = BankTransfer("0123456789")
processPayment(creditCard, 100.0)
processPayment(payPal, 50.0)
processPayment(bankTransfer, 200.0)
}
Output:
Processing credit card payment of 100.0
Payment successful!
Processing PayPal payment of 50.0
Payment successful!
Processing bank transfer payment of 200.0
Payment successful!
Explanation
- We create instances of
CreditCard
,PayPal
, andBankTransfer
, representing different payment methods. - The
processPayment
function takes aPaymentMethod
and an amount, processes the payment using the specific payment method’s logic, and prints the payment status.
In this real-world example, Kotlin sealed classes provide a structured and type-safe way to handle various payment methods in a payment processing system, ensuring each payment method’s specific logic is correctly implemented and used.
Benefits of Sealed Classes
- Compiler Checks: Sealed classes restrict the hierarchy, ensuring that all subclasses are handled explicitly.
- Enhanced Readability: By using sealed classes, code becomes more readable and maintainable, especially in scenarios with restricted hierarchies.
Kotlin sealed classes are a powerful tool for managing restricted hierarchies, such as handling different types of shapes, states, or events. By defining a sealed class, developers can ensure exhaustive handling of all possible subclasses, reducing the risk of runtime errors and improving code robustness.