2010-02-24 31 views
8

试图定义为默认的构造参数的存取方法,即:如何定义默认构造函数参数的存取方法?

class Person (age: Int) { 
    def age: Int = this.age 
} 

这显然会导致编译错误:暧昧参照重载定义,在类型=> int和值的类人既方法年龄年龄段类型Int类型匹配预期类型Int

在此上下文中是否有方法来区分成员方法名称和自动生成的成员值名称?

当然可以更改任一标识符的名称,但是在这种情况下是否有一种方法可以实际指定哪个标识符被引用?

回答

16

只需在要作为实例属性公开的构造函数参数前加上“val”即可。

+0

谢谢!只是自己想清楚了。:-)但是如果我想覆盖默认访问器呢?我想我仍然需要重命名参数? – 2010-02-24 16:01:37

+3

是的,你需要重命名参数(例如'age0'),然后定义访问器'def age = {Math.abs(age0)' – retronym 2010-02-24 17:33:47

6

使用

class Person (val age: Int) 

,如果你只是想要一个getter或

class Person (var age: Int) 

,如果你也希望有一个二传手。

3

上面的答案对于统一访问原则来说非常重要。如果您有或需要Java样式获取器和设置器,则还可以使用BeanProperty注释。

class Person(@scala.reflect.BeanProperty var age: Int) 

这将导致以下方法创建:

def getAge: Int = age 
def setAge(age: Int) = this.age = age 

如果改用为的BeanProperty如果val而不是变种,二传手不会被创建,只有吸气。

另外一个警告,setter方法不能从Scala内部调用。相反,您应该使用统一访问的标准Scala约定来设置值。

1

为了保持完整性并扩展以前的答案,还有涵盖here的技术。

总之,我总是有一个不变的值开始:

class Person (val age: Int) 

然后,如果你计算出你需要的变异值(或者你知道它之前),切换到:

class Person (var age: Int) 

然后,如果你需要验证或者做得到一些其他的计算或设置,重命名变量,构建模仿原来的命名存取,无需重构代码的其余部分:

class Person(var _age: Int) 
{ 
    def age = 
    { 
     println("age requested") 
     _age 
    } 
    def age_=(newAge: Int) = 
    { 
     assert(newAge > 0) 
     println(s"age changed from ${_age} to $newAge") 
     _age = newAge 
    } 
} 

当然,如果你不需要操作,你可以简化setter或getter。

对所有其他答案的荣誉,这确实是正确的,并且来得早。

相关问题