не может переопределить конкретный член без третьего члена, который переопределен обоими

Что означает следующее сообщение об ошибке?

не может переопределить конкретный член без третьего члена, который переопределен обоими (это правило предназначено для предотвращения "случайных переопределений");

Я пытался сделать стекируемые модификации черт. Это немного постфактум, так как у меня уже есть иерархия, и я пытаюсь изменить поведение, не переписывая много кода.

У меня есть базовый класс под названием AbstractProcessor, который определяет абстрактный метод вроде этого:

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

У меня есть пара существующих трейтов для реализации различных поведений onPush.

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

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

Так что это позволяет мне использовать new AbstractProcessor with Pass1 или new AbstractProcessor with Pass2.

Теперь я хотел бы выполнить некоторую обработку до и после вызова onPush в Pass1 и Pass2, минимизируя изменения кода в AbstractProcessor и Pass1 и Pass2. Я подумал о создании трейта, который делает что-то вроде этого:

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

И используя его с new AbstractProcessor with Pass1 with Custom, я получил это сообщение об ошибке.


person huynhjl    schedule 08.04.2010    source источник


Ответы (2)


Проблема в том, что существует неоднозначность между AbstractProcessor.onPush и Pass1.onPush. Последнее не отменяет первое, потому что Pass1 не расширяет AbstractProcessor.

Если сделать так, чтобы Pass1 и Pass2 расширяли AbstractProcessor, то проблема решалась.

person Daniel C. Sobral    schedule 09.04.2010
comment
К тому времени, когда я получил ваш ответ, я понял, что могу создать черту для onPush, и все это расширит. Кажется, меня смутило третье слово. Интересно, если бы без базового члена, который перекрывается обоими, это дало бы лучшую подсказку. - person huynhjl; 09.04.2010

Другое решение состоит в том, чтобы иметь трейт, который содержит только:

def onPush(i:Info): Unit

И смешайте эту черту с AbstractProcessor, Pass1 и Pass2. Компилятор больше не будет пытаться предотвратить «случайное переопределение».

person Brian Gordon    schedule 21.05.2015