Подтвердить что ты не робот

Использование Scala частного окончательного модификатора?

Что я могу использовать модификатор 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?

4b9b3361

Ответ 1

Хорошо, это сложно. Ваш вопрос: "Так почему же 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)
}

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

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

Ответ 2

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

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 ity?

Ответ 3

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

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

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

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