Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it good practice to make case classes sealed?

Tags:

scala

The main reason to seal classes seems to be that this allows the compiler to do exthaustivity searches when pattern matching on those classes. Say I have data types meant for pattern matching. Toy example:

sealed trait Statement
case class Assign(name: String, value: Int) extends Statement
case class Print(name: String) extends Statement
case class IfZero(name: String, thenn: Statement, els: Option[Statement]) extends Statement
case class Block(statements: List[Statement]) extends Statement

The use case for these classes would be to consume them through pattern matching:

def execute(statement: Statement): Unit = statement match {
    case Assign(name, value)      => ???
    case Print(name)              => ???
    case IfZero(name, thenn, els) => ???
    case Block(statements)        => statements foreach { execute(_) }
  }

To this end, the Statement trait is sealed so that the compiler can warn me if I forget one statement kind in the match statement. But what about the case classes? Case classes cannot inherit from each other, but traits and ordinary classes can. So, is it good practice to seal the case classes as well? What could go wrong if I don't?

like image 251
Emil Lundberg Avatar asked Jun 30 '15 02:06

Emil Lundberg


People also ask

Why we should use sealed class in C#?

1. We use sealed classes to prevent inheritance. As we cannot inherit from a sealed class, the methods in the sealed class cannot be manipulated from other classes. It helps to prevent security issues.

What does sealed trait mean?

Sealed traits are closed: they only allow a fixed set of classes to inherit from them, and all inheriting classes must be defined together with the trait itself in the same file or REPL command.

What is sealed case class in Scala?

Definition. The sealed is a Scala keyword used to control the places where given trait or class can be extended. More concretely, the subclasses and the implementations can be defined only in the same source file as the sealed trait or class.

Can case class be extended?

The answer is simple: Case Class can extend another Class, trait or Abstract Class. Create an abstract class which encapsulates the common behavior used by all the classes inheriting the abstract class.


1 Answers

You don't have to seal the case classes but you should mark them as final and therefore forbid any further inheritance relationship. Making them sealed is only useful when you want exhaustiveness checking on its subclasses, which is not a very likely use case.

Marking all classes as final by default is a good thing because it forbids the users of your API to change the behavior of these classes when they override its methods. If you didn't specifically design your class to be subclassed, it may happen that the subclassing leads to bugs in your application because the subclassed class is no longer doing what it was intended to do.

like image 109
kiritsuku Avatar answered Sep 22 '22 06:09

kiritsuku