您有与期限不可改变一个误解:
我认为其不可改变,因为我不能编辑一旦其创建的变量或访问 他们
这就是private的定义东西(方法,变量,...)。不变性是指您不能变异状态,即您不能更改某些东西的值,除非您创建它的新实例。
让我们看看一个例子:
trait Foo{
def myMutableValue: Int
}
class Clazz extends Foo{
var myMutableValue = 1
def changeState(): Int = {
myMutableValue += 1
myMutableValue
}
}
val bar = new Clazz
bar.changeState() // myMutableValue = 2
bar.changeState() // myMutableValue = 3
bar.changeState() // myMutableValue = 4
bar.myMutableValue // myMutableValue = 4
有了这个例子中,在你实例的Clazz
(bar
)您更改的是类属性的状态,在这种情况下myMutableValue
正在改变其值每次我调用changeState
。 请注意,该课程默认是公开的,changeState
也是公开的,并不意味着这是不可变的。
现在,让我们来看看一个不变的做法:
trait Foo{
def myMutableValue: Int
}
class Clazz extends Foo{
val myMutableValue = 1
def changeState(): Int = myMutableValue + 1
}
val instance = new Clazz
instance.changeState() // myMutableValue = 2
instance.changeState() // myMutableValue = 2
instance.changeState() // myMutableValue = 2
instance.myMutableValue // 1
采用这种方法,以changeState
每次调用将评估2,无论多少次,我调用该函数。也就是说,因为我们正在处理一个不可改变的值(val myMutableValue = 1
)。每次调用changeState
将执行评估并返回该值的副本。你不会以任何方式修改myMutableValue
的值。请致电this和this。
另外,请看看你的代码,你有一些错误:
- 按照惯例,类名应该大写(
Person
而不是person
)。
- 您不需要重新分配您的班级值与
def
(def getName
和def getDob
)。您可以按原样使用类值。
最后:
还没有最终在它面前这进一步让我 怀疑自己。
再一次,你在谈论不同的事情。与Java一样,final
是一个修饰符,用于防止您的课程成为extended
。
它不以任何方式与不变性相关
此外,如果要防止子类中的可变性,您必须使其所有成员final
(see this)。 因为你的例子是Scala编码你把所有的语言本身提供了供您使用的工具(例如val
,sealed
,final
)
请注意,我用了一个trait
解释可能使用def
。
编辑:about final
modifier and immutability
感谢@Silvio Mayolo和@puhlen的意见和澄清final
'final'在Java中也可以一个变量之前使用意味着什么接近Scala的“val”意味着什么,所以它涉及到不变性。它只是不在斯卡拉。 –
如果不是直接的,“final”确实涉及不变性。非final类的问题是可以创建一个子类并覆盖成员以使它们可变。多亏了多态,这可以让你认为你有一个不可变的类,但实际上正在使用一个可变的子类。 – puhlen