2013-04-19 16 views
15

Non sono sicuro di quale sia lo scopo della parola chiave override in scala. Se hoScala: qual è lo scopo dell'override

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

si comporta (a quanto pare almeno) esattamente lo stesso che fa a meno override.

risposta

38

Nel caso in cui si stanno attuando un metodo astratto come nel tuo esempio, non è strettamente necessario aggiungere il modificatore override.

Tuttavia, nel caso in cui si voglia il metodo override dalla superclasse, è necessario il modificatore override. Questo per evitare override accidentali che potrebbero accadere con la miscelazione della composizione - i tratti di mixing-in durante alcuni refactoring potrebbero facilmente introdurre una definizione di metodo che potrebbe essere scavalcata dal metodo definito nel corpo della classe, quindi la necessità di affermare esplicitamente che un il metodo è un override.

6

È per il controllo degli errori.
Supponiamo di avere

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

e poi si cambia forma per

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

In questo caso il "override" vi dirà che il foo in Triangle override nulla.

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

+0

Questo è corretto solo se il metodo che è stato sostituito è astratto, vedere la risposta axel22 s. Inoltre, entrambi i collegamenti sono irrilevanti perché si applicano a Java e C++, non a Scala in particolare. – Cubic

+1

Cubico, non importa se il metodo sovrascritto è astratto, questo può cambiare nel tempo. Il cambiamento dell'interfaccia, l'override aiuta a rimanere in sintonia. – ArtemGr

+0

La risposta implica che la parola chiave override si comporti come l'annotazione '@ Override' in Java. Questo è corretto solo quando si superano i metodi astratti. – Cubic

19

Nel tuo caso particolare, hai ricevuto una risposta completa da axel22. Voglio solo aggiungere che c'è almeno un altro caso in cui potresti incontrare un modificatore di override. La parola chiave può anche essere utilizzata con i metodi tratti.

Immaginate di avere una classe astratta:

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

e la sua attuazione concreta che consente di stampare su una console

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

Ora, si vuole creare un tratto che modificherà il suo comportamento. Osserva la seguente implementazione:

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

Si noti che un metodo ha due modificatori: abstract e override.Ciò è consentito solo per i caratteri e significa che il tratto deve essere miscelato in qualche classe che ha una definizione concreta del metodo in questione

Con la definizione di cui sopra, si può fare:

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

che sarà cedere il risultato

ABC

Molto nello stesso vano, è possibile aggiungere altri tratti:

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

Ora, quando si chiama

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

si vedrà:

ABC

L'utilizzo al di sopra di un modificatore override in tratti è una caratteristica distintiva in scala e non lo vedrà in Giava.