Search code examples
scalainheritancepolymorphismabstract-type

Scala: Difference between 'type A = XXX' and 'final type A = XX'?


assuming I have an abstract type AA and concrete type XXX:

trait AA {
  type A = XXX
  final type B = XXX
}

In this case in any subclass of AA, both type A and B cannot be overriden, so it appears that the keyword final is completely redundant. Is this statement correct?


Solution

  • It's hard to prove that they're exactly identical, but I'm going to argue that they are, minus a few useless quirks.

    Useless quirks

    First and most obviously, they give different error messages. But that's not all: it's technically possible to override A, you just can't override it to anything other than XXX:

    trait A1 extends AA {
      override type A = XXX  // Compiles, but doesn't really do anything.
    }
    

    On the other hand, you can't ever override B:

    trait A2 extends AA {
      override type B = XXX  // Does not compile.
    }
    

    Are there any useful differences?

    Again, I'm going to argue that there aren't. In a very detailed answer to the question Is it possible to override a type field, StackOverflow user 0__ notes that

    type T = C inevitably fixes T, which would kind of correspond to making a method final.

    and

    You can now easily see that it must be forbidden to further 'override' T

    followed by some explanation of how the type system would be inconsistent if you could override T to a different type. See that answer for the details.