trait Rectangular{
def topLeft:Point
def bottomRight:Point
def left=topLeft.x
def right=bottomRight.x
def width=right-left
//andmanymoregeometricmethods...
}
class Rectangle(val topLeft:Point,val bottomRight:Point)
extends Rectangular{
//othermethods...
}
在Rectangular中,他定义了一个抽象函数,他在类Rectangle中实现了它,并在主构造函数中使用了val。
这是特质的特例吗?这是预期的行为吗?
之前他描述过只有def可以覆盖def。但在这种情况下,val实现了一个抽象函数,这真的很奇怪。
答案 0 :(得分:3)
val
实际上是用于定义私有变量的语法糖和具有相同名称的公共getter方法,因此val
基本上包含def
。当您使用def
覆盖val
时,编译器将使用getter方法作为覆盖def
的函数。您还可以使用def
覆盖var
,def
定义了getter和setter方法(尽管我通常不会将此类行为视为“好”代码)。
使用val
定义抽象属性允许实现者选择是否要使用var
,def
或def
。
因此,如果作者声称只有def
可以覆盖{{1}},那么这是不正确的(也许是早期版本的Scala就是这种情况?)。
答案 1 :(得分:1)
不幸的是我从来没有读过那个博士(对我很遗憾)。但这是错误的。您可以使用def
或val
覆盖lazy val
。这种模式很常见。
为避免出现奇怪的行为,强烈建议避免使用抽象val
。