为什么允许scala中的最终变量更改值

时间:2017-02-14 07:50:41

标签: scala

为什么允许Scala中的最终变量更改值。根据我的理解,一旦宣布最终,他们就不应该被允许改变。

class foo()
{
  final var name = "abc"
  name = "xyz" // why this is allowed
}

3 个答案:

答案 0 :(得分:11)

final关键字与Java中的含义不同。

在Java中,它既可以意味着无法扩展或覆盖类或方法,也可以表示引用是不可变的。

在Scala final中只有第一个含义,而要有不可变引用,您应该使用val关键字。

class Foo {
  val name: String = "abc"
  // name = "xyz" // would be a compilation error

  final var surname: String = "def"
  surname = "uvw" // ok
}

class Bar extends Foo {
  override val name: String = "xyz"
  override var surname: String = "rst" // compilation error
}

答案 1 :(得分:7)

根据{{​​3}}(强调我的)定义

final

5.2.6最终

  

final修饰符适用于类成员定义和类定义。   最终的类成员定义可能不会在子类中重写。一个   最终的课程可能不会被模板继承。决赛是多余的   对象定义。最终类或对象的成员是隐式的   也是最终的,所以最终修饰符通常是多余的,   太。但请注意,常量值定义确实需要   显式最终修饰符,即使它们是在最终类中定义的   宾语。 final可能不适用于不完整的成员,也可能不适用   合并在一个密封的修饰符列表中。

由于Scala中的val定义已经意味着对它的引用是不可变的(与Java不同),因此在定义它时不必明确指定它。如果希望将值作为字节代码中的常量内联,则可以指定添加final修饰符。

根据var,final在这里仅表示“可能不会在子类中重写,但对变量的 immutability 一无所知:

scala> :pa
// Entering paste mode (ctrl-D to finish)

class Foo {
  final var name = "abc"
}

class Bar extends Foo {
  override var name = "yuval"
}

// Exiting paste mode, now interpreting.

<console>:16: error: overriding variable name in class Foo of type String;
 variable name cannot override final member
             override var name = "yuval"

答案 2 :(得分:2)

关于final,无论是否扩展或覆盖类/变量,它都会出现。

如果没有最终结果,您可以在子课程中重写

class Fruit {
  val color = "Green"
}

class AmericanFruit extends Fruit {
  override val color = "Red"
}

使用final,您不能将变量覆盖到您的子类。

final

此外,无法继承final类,

final class

val用于不可变数据。 (val表示不可变值)

例如

scala> val immutableName = "you can not change me"
immutableName: String = you can not change me

scala> immutableName = "change me"
<console>:12: error: reassignment to val
       immutableName = "change me"
            ^

对于mutable,您使用varvar作为变量)

scala> var mutableName = "you can change me"
mutableName: String = you can change me

scala> mutableName = "i am changed"
mutableName: String = i am changed