Scala对构造函数定义的属性的限制

Vin*_*ele 1 attributes constructor scala class

在Scala中,可以在构造函数中定义类属性.但是一旦你在那里声明它们,就不可能改变行为(getter和setter),就像你在类体中声明一样?

例:

class MyExample(var attribute : String)
{
    def attribute() //trying to override getter <- doesn't work
}

class MyExample(theAttribute : String)
{
   def attribute = theAttribute //overriding default accessor (was var)
}
Run Code Online (Sandbox Code Playgroud)

如果不可能,为什么会这样呢?当你向人们展示他们可以通过在构造函数中设置var或val来轻松创建属性而不关心getter和setter(他们可以根据需要改变)时,这似乎令人困惑,最终发现,事实上,你应该避免使用那些一种便利.

Vla*_*dim 7

让我们暂时想象可以覆盖生成的访问器方法:

class MyExample(var attribute : String)
{
    def attribute() = attribute + "abc" // won't compile!
}
Run Code Online (Sandbox Code Playgroud)

如果没有进一步的限定,就无法判断attribute方法体中的名称是指类字段还是递归到方法本身.

通过设计Scala方法和字段属于同一名称空间,这称为统一访问原则,可以在不破坏外部接口的情况下更改内部实现.

初步实施可以是:

class MyExample(val attribute : String)
Run Code Online (Sandbox Code Playgroud)

然后改为:

class MyExample (attr :String) {
   def attribute = attr toUpperCase 
}
Run Code Online (Sandbox Code Playgroud)

然后

class MyExample(var attribute : String)
Run Code Online (Sandbox Code Playgroud)

要么

class MyExample(attr : String) { 
    def attribute = attr toUpperCase 
    def attribute_= (a : String) { attr = a + "abc" } 
}
Run Code Online (Sandbox Code Playgroud)

所有这些都没有破坏任何依赖代码.

当字段被定义为构造函数的一部分时,自动生成的访问器方法是语法糖.糖可以简化快速原型设计,有助于保持代码简洁.尽管如此,每当您想要添加更多内容时,您必须使用完整语法.