cannot override a concrete member without a third member that's overridden by both
Asked Answered
P

2

10

What does the following error message mean?

cannot override a concrete member without a third member that's overridden by both (this rule is designed to prevent ``accidental overrides'');

I was trying to do stackable trait modifications. It's a little bit after the fact since I already have a hierarchy in place and I'm trying to modify the behavior without having to rewrite a lot of code.

I have a base class called AbstractProcessor that defines an abstract method sort of like this:

abstract class AbstractProcessor {
  def onPush(i:Info): Unit
}

I have a couple existing traits, to implement different onPush behaviors.

trait Pass1 {
  def onPush(i:Info): Unit = { /* stuff */ }
}

trait Pass2 {
  def onPush(i:Info): Unit = { /* stuff */ }
}

So that allows me to use new AbstractProcessor with Pass1 or new AbstractProcessor with Pass2.

Now I would like to do some processing before and after the onPush call in Pass1 and Pass2 while minimizing code changes to AbstractProcessor and Pass1 and Pass2. I thought of creating a trait that does something like this:

trait Custom extends AbstractProcessor {
  abstract override def onPush(i:Info): Unit = {
    // do stuff before
    super.onPush(i)
    // do stuff after
  }
}

And using it with new AbstractProcessor with Pass1 with Custom and I got that error message.

Perfection answered 8/4, 2010 at 21:34 Comment(0)
A
12

The problem is that there is ambiguity between AbstractProcessor.onPush and Pass1.onPush. The latter is not overridding the former because Pass1 does not extend AbstractProcessor.

If you make Pass1 and Pass2 extend AbstractProcessor, then the problem is solved.

Abercromby answered 9/4, 2010 at 0:20 Comment(1)
By the time I got your answer I figured out I could create a trait for onPush and have everything extends that. I guess I got confused by the "third" word. I wonder if "without a base member that's overriden by both" would give a better clue.Perfection
S
0

Another solution is to have a trait that contains just:

def onPush(i:Info): Unit

And mix that trait into AbstractProcessor, Pass1, and Pass2. The compiler will no longer try to prevent an "accidental override."

Slaton answered 21/5, 2015 at 0:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.