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

时间:2012-03-07 00:39:42

标签: class scala constructor attributes

在Scala中,可以在构造函数中定义类属性。但是一旦你在那里声明它们,就不可能改变行为(getters和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)
}

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

1 个答案:

答案 0 :(得分:7)

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

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

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

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

初步实施可能是:

class MyExample(val attribute : String)

然后改为:

class MyExample (attr :String) {
   def attribute = attr toUpperCase 
}

然后

class MyExample(var attribute : String)

或者

class MyExample(attr : String) { 
    def attribute = attr toUpperCase 
    def attribute_= (a : String) { attr = a + "abc" } 
}

所有这些都不会破坏任何相关代码。

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