34

我不确定override关键字的用途是什么,在 scala 中。如果我有

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

它的行为(显然至少)与没有override.

4

3 回答 3

69

如果您要实现示例中的抽象方法,则不一定要添加override修饰符。

但是,如果您想override从超类中获取具体方法,则override修饰符是必需的。这是为了避免混合组合可能发生的意外覆盖——在某些重构过程中混合特征很容易引入一个方法定义,该方法定义可以被类主体中定义的方法覆盖,因此需要明确说明方法是一个覆盖。

于 2013-04-19T17:37:41.043 回答
32

在您的特定情况下,您从 axel22 获得了全面的答案。我只想补充一点,至少还有一种情况可能会遇到覆盖修饰符。该关键字也可以与特征方法一起使用。

假设你有一个抽象类:

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")

这将产生结果

美国广播公司

同样徒劳,您可以添加更多特征:

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")

你会看见:

美国广播公司

上面在特征中使用覆盖修饰符是 scala 中的一个显着特征,您不会在 java 中看到它。

于 2013-04-19T19:06:07.577 回答
8

它用于错误检查。
假设你有

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 }

在这种情况下,“覆盖”会告诉您fooinTriangle不会覆盖任何内容。

另见:
http ://docs.oracle.com/javase/7/docs/api/java/lang/Override.html
http://en.wikipedia.org/wiki/C%2B%2B11#Explicit_overrides_and_final

于 2013-04-19T17:37:32.217 回答