I know that title is hard to understand, so here’s an example of the issue:
open class AbstractB(val param1: String)
class B(param1: String) : AbstractB(param1)
open class AbstractA(open var param: AbstractB)
class A(override var param: B) : AbstractA(param)
So, IntelliJ IDEA says that Var-property type is 'B', which is not a type of overridden
But, if we change class AbstractA param to val the issue doesn’t appear:
open class AbstractB(val param1: String)
class B(param1: String) : AbstractB(param1)
open class AbstractA(open val param: AbstractB)
class A(override val param: B) : AbstractA(param)
class B2 : AbstractB("2")
val b1 = B("1")
val b2 = B2()
val a: AbstractA = A(b1) // b2 is incompatible with A() constructor because it requires B not AbstractB
a.param = b2 // b2 is compatible, since a.param is AbstractA.param which is AbstractB
However, b2 is passed to the underlying A.param, which does not accept B2 (B2 extends AbstractB but not B). This leads to type errors.
Therefore, var overrides must always use the same type, while val overrides may use a more specific type.
This is because var generates both a getter (return type) and a setter (argment type), while val only generates a getter (return value).