11
votes

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.

1
Scala would have been a much simpler and better language if it didn't have to support Java interop. Would have been easier for people to learn as well.M.K.
This is also worth a read.jwvh
@yuval-itzchakov I have already familiarized myself with that question and its answers. There are many good points, but I couldn't find an answer to my problem there. The answers seem to focus on differences in extendability of the two solutions. If both, the trait and the abstract class would be sealed, I couldn't extend them outside the file (or inherit from in Java?), right? Additionally, if no constructor parameters are used, I think most of the answers are rendered useless to this particular case.vaiski

1 Answers

11
votes

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