def vs val To Define Abstract Members
The short story is that if you want to declare an abstract member in a trait, as a def or val field that may be later fulfilled in an implementing class, the most flexible approach is to define the member as a def. The primary benefit of this approach is explained in Figure.
val can override a def
def cannot override a val
As the error message implies, using val means a guarantee that the variable is stable and immutable, and def does not mean that same guarantee.
In general, overriding says, that downgrading is not allowed But while using def instead of val we are downgrading the stable and immutable behavior of val.
If you use var field instead of val the error message will go away. But Scala/FP developers don’t use var fields.