2014-06-09 121 views
1

考虑下面的例子:斯卡拉:覆盖高清与VAL

abstract class Item { 
    def price: Double 
    def description: String 
} 

class SimpleItem1(override val price: Double, override val description: String) extends Item{}  
class SimpleItem2(val price: Double, val description: String) extends Item{} 

它成功地编译和两个扩展类具有相同的方法。他们真的是一样的吗?如果不是 - 有什么区别?如果是,请给我解释一下,例如:为什么他们决定'覆盖'在这里是可选的?

回答

9

因为pricedescriptionItem中是抽象的,所以不需要使用override修饰符。如果他们有默认的实现,你将不得不添加override修饰符。

因此,在SimpleItem1中,修饰语是多余的。在某些情况下,添加一个“以防万一”是有道理的override。例如,如果您定义了一个可能要混入具有默认实现的类的特征。


下面是一个例子,其中override会有所作为:

trait Item0 { 
    def price: Int 
} 

trait Item1 extends Item0 { 
    def price = 33 
} 

trait Item2 extends Item0 { 
    override def price = 33 
} 

object Foo1 extends Item1 // ok 
object Foo2 extends Item2 // ok 
object Foo3 extends Item0 with Item1 // ok 
object Foo4 extends Item2 with Item1 // NOPE! 
object Foo4 extends Item1 with Item2 // aha! 

一般来说,你应该避免使用override在可能的情况。

+6

很好的答案,除了最后一句话。没有写'override'没有什么好处,它有助于使代码更加清晰和安全,以便将来添加。一些保存的按键不值得担心(你的例子是一个很好的例子,不应该写代码)。 – sschaef

+1

@sschaef - 我认为这是不错的设计,不适合重载的东西,我支持这种说法。我很少必须使用重载,并且我不觉得我错过了任何东西。有像Swing这样的框架可以处理重载,但是一般来说,如果你设计你的类,你应该可以不用它。 –

+0

@ 0__ - 我认为sschaef的意思是 - “每次重写时都应该重写,即使语法允许,也不应该跳过这个单词”。他写这篇文章是因为你最后一句话有点混乱。我个人把它理解为:“当你压倒性的时候,如果可以的话,不要用'重写'这个词,而且语法允许你”。尽管如此,我仍然可能错在谁的意思是什么:)。 – GrayR