Требовать, чтобы другой метод вызывался поверх функции - PullRequest
0 голосов
/ 19 июня 2020

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

Например, если в суперклассе Super есть функция setup, я хочу чтобы убедиться, что каждый подкласс вызывает super.setup() до того, как подкласс сделает что-нибудь еще, чтобы убедиться, что все уже настроено до использования других методов.

Лучшее, что я мог получить, это то, что не очень просто или идиомати c

class CalledSuper

class Super {
  def setup() = {
    println("Doing some necessary things")
    new CalledSuper
  }

  def printText(s: String)(implicit ev: CalledSuper) = println(s)
}

class Foo extends Super {
  override def setup() = {
    //printText("In subclass's method") error: Could not find implicit value
    implicit val proof = super.setup()
    printText("In subclass's method")
    proof
  }

  def fooBar() = {
    printText("I don't need to call super.setup")(new CalledSuper)
  }
}

Это не очень хорошо, хотя

  1. Это заставляет меня назначить результат setup на implicit val.
  2. Он заставляет мой переопределенный метод setup возвращать объект CalledSuper.
  3. Он заставляет меня заставить все методы в классе Super принимать объект CalledSuper.
  4. Он работает только с методами, находящимися внутри класса Super. Функция подкласса setup может по-прежнему использовать другие методы перед вызовом setup. Однако это не слишком большая проблема.

Моя основная проблема связана с №3. Это неудобно, потому что, если у меня есть какой-то другой метод fooBar, который также должен использовать метод printText (который в настоящее время принимает неявный параметр), но не требует вызова super.fooBar, это просто раздражает, потому что мне нужно без нужды создавать объект CalledSuper, даже если в этом нет необходимости.

Мне было интересно, есть ли лучший способ потребовать вызова метода перед некоторыми другими методами (не только для вызова super.foo, но и для того, чтобы требовать вызываемый метод), так как я не смог найти никаких вопросов по этому поводу для Scala. Я в порядке с "хаками" и схематичными обходными путями, если они не включают сборку целых плагинов компилятора (или чего-либо еще в этом масштабе).

EDIT: Чтобы уточнить, пример с super.setup() был только пример. Может быть другой метод, например baz, который не должен вызывать super.baz(), но должен вызывать validate() или что-то в этом роде.

1 Ответ

3 голосов
/ 19 июня 2020

Я предлагаю вам разработать свою стратегию переопределения немного иначе:

class Super {
  def superSetup() = {
    println("Doing some necessary things")
  }

  final def setup() = {
    superSetup()
    setupCustomize()
  }

  def setupCustomize() = {
  }

}


class Foo extends Super {
  override def setupCustomize() = {
    printText("In subclass's method")
  }
}

Если вы не хотите, чтобы порядок superSetup изменялся, сделайте его частью реализации, которая равна final .

...