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