2011-06-27 57 views
6

我有类似:如何访问和改变斯卡拉私人领域?

class Address(private var street:String, private var city: String, private var postCode: String) extends Model 

当我尝试这样做:

address = new Address(....) 
address.city = "changed" 

我得到的编译错误。 那么解决方案是什么?请注意,这些字段必须保持私密。

此外,还有一种快捷的语法,而不是在类中的所有字段都是私有的时候重复关键字private?

回答

18

这里似乎有一个根本性的误解。 Scala中的所有字段都是私有的。这不仅仅是默认的,也不是可选的。

例如,假设你有这样的:

class Address(var street: String) 

其中street存储领域是私人。说你这样做:

val x = new Address("Downing") 
println(x.street) 

此代码不能直接访问私有领域streetx.street获取方法

说你这样做:

x.street = "Boulevard" 

此代码不能直接修改私有字段streetx.street =实际上是方法x.street_=,这是一个setter方法

您无法直接访问Scala中的字段。一切都是通过获得者和制定者完成的。在斯卡拉,每个领域都是私人的,每个领域都有获得者,每个领域都有制定者。

+16

这个答案的语气似乎几乎...生气? –

+0

我不会说它很生气。感谢您解释概念@Danial – ace

+0

不生气,强调。我过于强调,因为我知道这一点是以前做出的。我试图确认这一点。 –

5

您可以定义存取函数是这样的:

class Address(private var _street: String, private var _city: String, private var _postCode: String){ 
    def street = _street 
    def street_=(street: String) = _street = street 

    def city = _city 
    def city_=(city: String) = _city = city 

    def postCode = _postCode 
    def postCode_=(postCode: String) = _postCode = postCode 
} 

需要重命名字段(这可能与命名的参数冲突),并且构造忽略突变时,实例化类是一个已知的问题,但目前没有努力改善这种状况。

+0

谢谢。但是当我们在构造函数中拥有私有字段时,在scala中通过这种方式看起来相当麻烦。如果我们为该领域定义标准的getter和setter,然后执行诸如address.setStreet(“chnaged”)之类的东西,会不会更好? – ace

+3

'街道'和'street_ ='_是标准的getter和setter在斯卡拉的名字。谷歌为“统一访问原则”。 –

+1

@amc用public getter和setter定义私有字段的语法是'class Address(var street:String)'。 –