Использовать частный финальный модификатор Scala? - PullRequest
12 голосов
/ 06 сентября 2011

Для чего я могу использовать модификатор private final в Scala?

Учитывая приведенный ниже код:

1| class A { def callFoo = foo; private final def foo = "bar of A" }
2| class B extends A { private final def foo = "bar of B"}
3| println((new A()).callFoo)
4| println((new B()).callFoo)

Линия 3 и 4 отпечатка:

1| bar of A
2| bar of A

Понятно, почему строка 2 не печатает bar of B, потому что на самом деле есть два определения foo, а последнее в B не переопределяет первое в A. В противном случае Scala потребует override - вместо модификатор final.

Так почему же Scala не просто запрещает комбинацию модификаторов private final?

Ответы [ 3 ]

14 голосов
/ 06 сентября 2011

Хорошо, это сложно.Ваш вопрос: «Так почему же Scala не просто запрещает комбинацию модификаторов private final?» основана на предположении, что эта комбинация не имеет смысла.

Допустим, вы правы (и вы, за исключением крошечной детали, которая будет упомянута позже).Я не парень компилятор, но с моей точки зрения "просто запретить", вероятно, не так просто (по крайней мере, в этом случае).И почему кто-то пытается это сделать?Каковы компромиссы?Только то, что что-то бесполезно, не обязательно означает, что оно приносит вред.Только не используйте это ...

Теперь вот крошечная деталь, которую вы, кажется, упустили из виду.Модификатор private является модификатором видимости, что означает, что class B не знает о его существовании.Но модификаторы видимости Scala немного сложнее, чем, скажем, Java.Предположим, что по какой-либо причине вам потребуется код, показанный в следующем фрагменте кода, компилятор не допустит его.

package scope

class A {
  def callFoo = foo;
  private[scope] final def foo = "bar of A"
}
class B extends A {
  private[scope] final def foo = "bar of B"
}

object Main extends App {
  println((new A()).callFoo)
  println((new B()).callFoo)
}

Это одна из ошибок, предоставленных компилятором: "method fooне может переопределить последний элемент ".

Итак, поехали.Scala просто запрещает эту комбинацию;)

3 голосов
/ 06 сентября 2011

Обращаясь к более широкому вопросу,

Так почему же Scala не просто запрещает комбинацию модификаторов private final?

Это новое правило, и при этомновое исключение.Это делает язык более сложным и абсолютно безрезультатным.Зачем все усложнять без всякой веской причины?

Это то, что делает Java, что очень не нравится Одерскому.Чтобы язык стал более сложным, должно быть какое-то усиление.

3 голосов
/ 06 сентября 2011

Первоначально я думал, что это должно предотвратить переопределение частных методов во вложенных классах, но, очевидно, нет:

class A {
  private final def foo = 0

  class B extends A {
    override def foo = 1
  }
}

error: method foo overrides nothing
           override def foo = 1
                        ^

Возможно, это просто для упрощения рефакторинга?Так что, если у вас есть метод final, попробуйте сделать его private, и вы обнаружите, что он не должен быть private в конце концов, вы не потеряете final в этом процессе?

...