Q:

What are all the overriding rules between def, val, lazy val, and var in scala?

In scala, there are four kinds of member modifier, i.e. def, val, lazy val, var. There is a seemingly complicated and inconsistent set of rules regarding overriding, for instance, def can be overridden by val, while not the other way around. It would be great to see a full list of all these rules.

A:

All overridings in scala fall into two categories, the first case is to override an abstract member(in trait or abstract class) and the other is to override a concrete member:
Override concrete members
def, val, lazy val, var might all be overridden in subclasses:

def: can be overridden by all kinds of members(def, val, lazy val, and var).

val: can only be overridden by val.

lazy val: can only be overridden by lazy val.

var: a concrete var cannot be overridden.

Override abstract members
lazy val cannot be abstract, so there are only three rules:

def: can be overridden by all kinds of members(def, val, lazy val, and var).

val: can be overridden by val and lazy val.

var: can be overridden by (1) var, or (2) a pair of read and write operations implemented by def, val, or lazy val.

EDITED:
As pointed out by @iuriisusuk, please refer to the related section in spec for a formal description.

