Scala: какова цель 'override'

Я не уверен, какова цель ключевого слова override, в scala. Если у меня есть

trait Shape { def foo(v: Int) }
class Triangle extends Shape { override def foo(v: Int) {} }

он ведет себя (по-видимому, по крайней мере) точно так же, как и без override.

Ответы

Ответ 1

В случае реализации абстрактного метода, как в вашем примере, нет необходимости добавлять модификатор override.

Однако, если вы хотите override создать конкретный метод из суперкласса, необходим модификатор override. Это делается для того, чтобы избежать случайных переопределений, которые могут произойти с композицией смешивания. Характеристики смешения во время некоторого рефакторинга могут легко ввести определение метода, которое может быть переопределено методом, определенным в теле класса, следовательно, необходимо явно указать, что a метод является переопределением.

Ответ 2

В вашем конкретном случае вы получили исчерпывающий ответ от axel22. Я просто хочу добавить, что есть хотя бы еще один случай, когда вы можете столкнуться с модификатором переопределения. Ключевое слово также может использоваться с методами trait.

Представьте, что у вас есть абстрактный класс:

abstract class Writer {
  def print(str: String)
}

и его конкретную реализацию, которая выводится на консоль

class ConsoleWriter extends Writer {
  def print(str: String) = println(str)
}

Теперь вы хотите создать признак, который изменит его поведение. Посмотрите на следующую реализацию:

trait Uppercase extends Writer {
  abstract override def print(str: String) = 
    super.print(str.toUpperCase())
}

Обратите внимание, что метод имеет два модификатора: abstract и override. Это разрешено только для признаков, и это означает, что черта должна быть смешана с некоторым классом, который имеет конкретное определение рассматриваемого метода.

С помощью вышеприведенного определения вы можете сделать:

val writer = new ConsoleWriter with Uppercase
writer.print("abc")

который даст результат

ABC

Многое в том же напрасно, вы можете добавить больше черт:

trait WithSpaces extends Writer {
  abstract override def print(str: String) = 
    super.print(str.split("").mkString(" ").tail)
}

Теперь, когда вы вызываете

val writer = new ConsoleWriter with Uppercase with WithSpaces
writer.print("abc")

вы увидите:

A B C

Вышеупомянутое использование модификатора переопределения в признаках является отличительной особенностью в scala, и вы не увидите его в java.

Ответ 3

Это для проверки ошибок.
Предположим, что у вас есть

trait Shape { def foo(v: Int) = 1 }
class Triangle extends Shape { override def foo(v: Int) = 2 }

а затем вы измените Shape на

trait Shape { def bar(v: Int) = 1 }

В этом случае "переопределение" скажет вам, что foo в Triangle ничего не отменяет.

См. также:
http://docs.oracle.com/javase/7/docs/api/java/lang/Override.html
http://en.wikipedia.org/wiki/C%2B%2B11#Explicit_overrides_and_final