这个类是不可变的还是可变的

时间:2017-07-30 23:38:37

标签: scala

下面的Scala类是可变的还是不可变的?

我认为它是不可变的,因为我无法编辑变量或在创建变量后访问它们但是让我怀疑自己是因为它使用其函数返回变量的当前实例。它也没有最终在它面前,这进一步让我怀疑自己。

class person(name:String, dob:String){
  def getName = name
  def getDob = dob
  def display() = {
    println("Name "+name+" dob: "+dob)
  }
}

谢谢,

1 个答案:

答案 0 :(得分:1)

您对术语不可变有误解:

  

我认为它不可变,因为我无法编辑变量或访问   它们一旦创建就

私有事物(方法,变量,......)的定义。不变性指的是你不能改变状态,也就是说,除非你创建一个新的实例,否则你不能改变某些东西的价值。

让我们看一个例子:

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

通过该示例,在Clazzbar)的实例中,您正在更改类属性的状态,在这种情况下{{1}每次调用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 的每次调用都将计算为2。也就是说,因为我们正在处理不可变值(changeState)。每次val myMutableValue = 1的调用都将执行评估并返回该值的副本。您未以任何方式修改changeState的价值。

请查看thisthis

另外,请看一下你的代码,你有一些错误:

  • 按照惯例,类名应大写(myMutableValue而不是Person)。
  • 不需要使用person defdef getName)重新分配您的班级值。您可以按原样使用类值。

最后:

  

它也没有最终在它面前,这进一步使我   怀疑自己。

再一次,你在谈论不同的事情。与Java一样,def getDob是一个修饰符,可以防止您的类成为final它不以任何方式与不变性相关在adition中,如果你想防止你的子类中的可变性,你必须让他们的所有成员extendedsee this) 。 由于您的示例是使用Scala编写的,因此您可以使用该语言本身提供的所有工具(例如finalvalsealed

请注意,我已使用final来解释trait的可能用途。

编辑:about final modifier and immutability

感谢@Silvio Mayolo和@puhlen对def

的评论和澄清