如何为默认构造函数参数定义访问器方法?

时间:2010-02-24 15:46:43

标签: scala

尝试为默认构造函数参数定义一个访问器方法,即:

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

这显然会导致编译器错误:对重载定义的模糊引用,类类型中的方法年龄类型=>类中的Int和value age类型Int的类匹配期望类型Int

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

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

4 个答案:

答案 0 :(得分:16)

只需将“val”放在要作为实例属性公开的构造函数参数前面。

答案 1 :(得分:6)

使用

class Person (val age: Int)

如果你只想要一个吸气剂或

class Person (var age: Int)

如果你还想要一个制定者。

答案 2 :(得分:3)

上面的答案对于统一访问原则是很好的。如果您有或者需要Java样式的getter和setter,您也可以使用BeanProperty注释。

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

这将导致创建以下方法:

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

如果您使用BeanProperty代替val而不是var,则不会创建setter,只会创建getter。

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

答案 3 :(得分:1)

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

总而言之,我总是以不可变的值开头:

class Person (val age: Int)

然后,如果您发现需要改变该值(或者事先知道它),请切换到:

class Person (var age: Int)

然后,如果你需要在get或set上验证或做一些其他的计算,重命名变量并构建模仿你原始命名的访问器,不需要重构其余的代码:

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。

赞赏所有其他答案,这些答案确实是正确的,而且要早得多。