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.
Also, can not inherit the 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"