2

I am looking to define the following algebraic data type in scala:

sealed trait Beat
case object Rest extends Beat
case object Hit extends Beat

Is there any difference, if I were to define this instead as:

abstract sealed class Beat
case object Rest extends Beat
case object Hit extends Beat

i.e. using an abstract sealed class instead of a trait? The definitions appear to be equivalent.

Rich Ashworth
  • 1,995
  • 4
  • 19
  • 29

2 Answers2

6

There is no difference in the meaning of sealed whether you put it on an (abstract) class or a trait. So in your case, the two examples are indeed (almost) equivalent.

A difference between an abstract class and a trait comes apparent when a subclass wants to inherit from another class: A class/trait can always only extend a single class, but multiple traits. For example:

class SomeClass

sealed trait Beat1
abstract sealed class Beat2

case object Rest1 extends SomeClass with Beat1 // ok
case object Rest2 extends SomeClass with Beat2 // compile error

Otherwise, an abstract class and a trait are pretty much equivalent. The biggest differences in practice probably only appear once you are concerned about binary compatibility (kind of out of scope for this answer).

gzm0
  • 14,752
  • 1
  • 36
  • 64
3

To add to gzm0's answer, a further difference between an abstract sealed class and a trait is that an abstract sealed class, like any other class but unlike a trait, can have constructor parameters:

abstract sealed class Duck(sound: String)

case object RealDuck extends Duck("quack")
case object RubberDuck extends Duck("squeak")
Community
  • 1
  • 1
Ben
  • 1,414
  • 2
  • 13
  • 18