While trying to learn Akka, I often find examples with a class hierarchy similar to this:
sealed trait Message
case class TextMessage(user: String, text: String) extends Message
case class StatusMessage(status: String) extends Message
However, in the Scala docs there's a following example:
abstract class Notification
case class Email(sourceEmail: String, title: String, body: String) extends Notification
case class SMS(sourceNumber: String, message: String) extends Notification
case class VoiceRecording(contactName: String, link: String) extends Notification
What's the difference in using a sealed trait vs. an abstract class (or sealed abstract class in this case) as a base class without constructor parameters for a class hierarchy? Are there some advantages in using one over the other?
Edit:
Specifically, if both, the trait and the abstract class are sealed, I can't extend them outside the file, right? In that case I couldn't inherit from them in Java either? If that's the case, being sealed would render most of the arguments found in the suggested duplicate useless since they refer to inheritance outside the file.
Trait supports multiple inheritance. Abstract Class supports single inheritance only. Trait can be added to an object instance. Abstract class cannot be added to an object instance.
The abstract class includes abstract and non-abstract methods. You cannot instantiate an abstract class. The sealed class prevents inheritance and you cannot use it as a base class.
The sealed keyword is used to control the extension of classes and traits. Declaring a class or trait as sealed restricts where we can define its subclasses — we have to define them in the same source file.
Sealed classes and interfaces represent restricted class hierarchies that provide more control over inheritance. All direct subclasses of a sealed class are known at compile time. No other subclasses may appear outside a module within which the sealed class is defined.
In this particular case there are no differences except that you can't extend multiple abstract classes
but you can extend multiple traits
.
You should check other answers (as mentioned in the comments) to see the actual differences between abstract classes and traits. If you are just going to use an abstract class
or a trait
to define the type hierarchy as in this case, then there are no differences.
E.g. you could to the following:
trait A
trait B
case class C(a: Int) extends A with B
but you can't do:
abstract class A
abstract class B
case class C(a: Int) extends A with B
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With