Search code examples
scalainheritancemixins

Is "A with B" a type?


In Scala we use mix-in like this:

class C extends A with B

I understand this declaration as C is a subclass of A with B. Is this true? Or C is just subclass of both A and B(I don't think it's possible on JVM which doesn't support multi-inheritance)?

If A with B is a type, why doesn't this line work?

classOf[A with B]

Another reason why I consider A with B a type is the fact that it can be used in pattern match:

val c = new C
val u = c match { case a: A with B => 1 } // 1

Solution

  • Scala supports multiple inheritance via traits. Any class can extend 0 or 1 class, but can also "mix in" any number of traits. (There is a bit of compiler magic that rearranges things behind the scenes to conform to the JVM's limitations) The syntax is along the lines of

    class MyClass extends [ClassOrTrait] with [Trait] with [AnotherTrait] with ...
    

    So your class C definition is more like

    class ((C extends A) with B) than like class (C extends (A with B))

    A with B is a type, and can be used as a type alias, but the classOf method wants a class:

    scala> type AB = A with B
    defined type alias AB
    
    scala> classOf[AB]
    <console>:11: error: class type required but A with B found
                  classOf[AB]
                          ^
    

    vs

    scala> class AB extends A with B
    defined class AB
    
    scala> classOf[AB]
    res12: Class[AB] = class AB