4

I'm trying to override a trait member with an abstract one, which seems straightforward but won't actually compile.

Here's a boiled down example of what I'm trying to do:

// not my code:
trait Base {
  val x = new T {}
  trait T {}
}

// my code:
trait Sub extends Base {
  // compile error; see below
  override val x: T2

  // this compiles, but doesn't force `Impl` to implement `x`
//  override val x: T2 = null

  trait T2 extends T {
    val someAddition: Any
  }
}

object Impl extends Sub {
  // should be forced to implement `x` of type `T2`
}

Here's the compiler error:

Error:(7, 7) overriding value x in trait Sub of type Sub.this.T2;
 value x in trait Base of type Sub.this.T has incompatible type;
 (Note that value x in trait Sub of type Sub.this.T2 is abstract,
  and is therefore overridden by concrete value x in trait Base of type Sub.this.T)
trait Sub extends Base {
      ^
dwickern
  • 3,519
  • 1
  • 14
  • 21

1 Answers1

6

A technique I can think of is to use a different name for the abstract member and getting the concrete member to call this one instead.

trait Sub extends Base {
  val y: T2
  override val x = y

There's an interesting discussion about this over in Java land.

Community
  • 1
  • 1
bjfletcher
  • 11,168
  • 4
  • 52
  • 67
  • That would work, although it forces the client to switch from `sub.x` to `sub.y` (if the client needs the additional stuff from `T2`). – dwickern Jun 20 '15 at 17:56