Scala Tutorial
Basics
Control Statements
OOP Concepts
Parameterized - Type
Exceptions
Scala Annotation
Methods
String
Scala Packages
Scala Trait
Collections
Scala Options
Miscellaneous Topics
In Scala, the sealed
keyword has a special purpose when used in conjunction with traits and abstract classes. A sealed
trait or class can only be extended within the same source file. This is a powerful feature, especially when combined with pattern matching, as it allows the compiler to perform exhaustiveness checks.
Exhaustiveness Checking: When pattern matching against cases of a sealed trait, the compiler can warn you if you've missed handling any case. This helps ensure that you've covered all possible cases, making your code more robust.
Controlling Inheritance: By sealing a trait or class, you prevent external inheritance. This means you have complete visibility and control over all the subtypes of your trait or class. This can be useful to ensure a specific set of implementations, especially when designing libraries.
Consider the following example of a sealed trait Shape
and its implementations:
sealed trait Shape case class Circle(radius: Double) extends Shape case class Rectangle(width: Double, height: Double) extends Shape
If you were to pattern match on an instance of Shape
, the compiler would know all the possible types it could be:
def area(shape: Shape): Double = shape match { case Circle(radius) => Math.PI * radius * radius case Rectangle(w, h) => w * h // No need for a default case (using `_`) because we've covered all possibilities }
If you missed one of the cases in the pattern match, the compiler would give a warning, saying that your pattern match is not exhaustive.
File Limitation: The restriction that all subtypes must be in the same file is occasionally seen as limiting, especially in larger codebases. However, this limitation is what allows the compiler to perform exhaustiveness checks.
Combining with abstract class
: You can also use sealed
with abstract class
in a similar way to trait
. The decision to use a trait or an abstract class comes down to other factors (e.g., whether you want to allow multiple inheritance).
Extending Further: While external code cannot extend a sealed trait, they can still extend the concrete implementations of that trait. If you want to prevent that as well, you would mark the concrete implementations as final
.
The sealed
modifier in Scala is a powerful tool to provide controlled inheritance and gain compiler-assisted checks for pattern matching. It helps in building safer and more predictable hierarchies, making it easier to reason about the code.
Scala Sealed Trait Example:
A sealed trait is a trait that can only be extended by classes or objects declared in the same file.
sealed trait Animal case class Dog(name: String) extends Animal case class Cat(name: String) extends Animal
Scala Sealed Trait Pattern Matching:
Sealed traits are often used with pattern matching for exhaustive matching.
def animalSound(animal: Animal): String = animal match { case Dog(_) => "Woof" case Cat(_) => "Meow" }
Scala Sealed Trait vs. Abstract Class:
Sealed traits offer more control over inheritance, preventing external extensions.
sealed trait Shape case class Circle(radius: Double) extends Shape case class Rectangle(width: Double, height: Double) extends Shape
Scala Sealed Trait Inheritance:
Subclasses of a sealed trait must be defined in the same file, providing a clear hierarchy.
sealed trait Color case object Red extends Color case object Blue extends Color
Sealed Trait and Case Class in Scala:
Combining sealed traits with case classes enhances pattern matching.
sealed trait Result case class Success(message: String) extends Result case class Failure(reason: String) extends Result
Scala Sealed Trait Sealed Abstract Class:
Sealed traits can be seen as a form of sealed abstract class, restricting inheritance.
sealed abstract class Fruit case class Apple() extends Fruit case class Orange() extends Fruit
How to Use Sealed Traits for Pattern Matching in Scala:
Leverage sealed traits to ensure comprehensive pattern matching.
sealed trait Day case object Monday extends Day case object Tuesday extends Day
Scala Sealed Trait Sealed Trait Hierarchy:
The sealed trait hierarchy is limited to subclasses defined in the same file.
sealed trait Vehicle case class Car(model: String) extends Vehicle case class Bike(model: String) extends Vehicle