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

jac*_*ack 5 scala

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

class foo()
{
  final var name = "abc"
  name = "xyz" // why this is allowed
}
Run Code Online (Sandbox Code Playgroud)

ste*_*ino 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
}
Run Code Online (Sandbox Code Playgroud)


Yuv*_*kov 8

finalScala规范的定义(强调我的):

5.2.6最终

final修饰符适用于类成员定义和类定义.最终的类成员定义可能不会在子类中重写.最终的类可能不会被模板继承.final对于对象定义是多余的.最终类或对象的成员也是最终的,因此最终修饰符对于它们来说通常也是多余的.但请注意,常量值定义确实需要显式的最终修饰符,即使它们是在最终类或对象中定义的.final可能不适用于不完整的成员,也可能不会在一个带有密封的修饰符列表中组合.

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

根据var,final在这里仅表示"可能不会在子类中被覆盖",但是对变量的不变性一无所知:

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"
Run Code Online (Sandbox Code Playgroud)


pra*_*upd 5

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

没有 final 你可以在你的子类中覆盖

class Fruit {
  val color = "Green"
}

class AmericanFruit extends Fruit {
  override val color = "Red"
}
Run Code Online (Sandbox Code Playgroud)

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

最终的

还有,不能继承final类,

最后一节课

使用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"
            ^
Run Code Online (Sandbox Code Playgroud)

对于可变的,您使用var(var用于变量)

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

scala> mutableName = "i am changed"
mutableName: String = i am changed
Run Code Online (Sandbox Code Playgroud)