Why Final variables in scala are allowed to change values

Regarding final, it comes into picture whether you extend or override the class/variable or not.

Without final you can override in your child class

class Fruit {
  val color = "Green"
}

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

With final, you can not override variable to your child class.

final

Also, can not inherit the final class,

final class

Use val for immutable data. (val for immutable value)

example

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"
            ^

And for mutable, you use var (var for variable)

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

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

The final keyword does not bear the same meaning it does in Java.

In Java it can both mean that a class or method cannot be extended or overridden and that a reference is immutable.

In Scala final only bears the first meaning, while to have an immutable reference you ought to use the val keyword.

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
}

final definition per the Scala Specification (emphasis mine):

5.2.6 final

The final modifier applies to class member definitions and to class definitions. A final class member definition may not be overridden in subclasses. A final class may not be inherited by a template. final is redundant for object definitions. Members of final classes or objects are implicitly also final, so the final modifier is generally redundant for them, too. Note, however, that constant value definitions do require an explicit final modifier, even if they are defined in a final class or object. final may not be applied to incomplete members, and it may not be combined in one modifier list with sealed.

Since a val definition in Scala already means that the reference to it is immutable (unlike Java), you don't have to explicitly specify that when defining it. If you want the value to be inlined as a constant in the byte code, you can specify add the final modifier.

As per var, final here only means "may not be overridden in subclasses", but says nothing about the immutability of the variable:

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"

Tags:

Scala