Simon Marynissen
Simon Marynissen

Reputation: 253

Kotlin properties cannot be overridden with subinterface

In the following stripped down example, can you explain why the Kotlin compiler complains when overriding a that we restrict its type further(compiler message: Var-property type is 'B', which is not a type of overriden public abstract var a: A)

interface A

interface B : A {
    fun someFunc():Boolean
}

class C : B {
    override fun someFunc(): Boolean {
        return true
    }
}

abstract class D {
    abstract var a: A
}

class E : D() {
    override var a : B = C()

    fun otherFunc() {
        println(a.someFunc())
    }
}

Furthermore, the compiler does not complain with the following snippet:

open class G

class H : G()

abstract class F {
    abstract val g: G
}

class I : F() {
    override var g : H = H()
}

So I guess there is something going on with interface inheritance, which is not there with classes.

Upvotes: 3

Views: 684

Answers (1)

Oliver Charlesworth
Oliver Charlesworth

Reputation: 272762

Your first code snippet fails to compile, because otherwise weirdness like this would be possible:

val d: D = E()
d.a = object : A {}  // Some other sub-type of A, but definitely not a sub-type of B

This is really a variant (no pun intended) of the lack of method parameter covariance in Java - especially given that a Kotlin var property is really just syntax sugar for a getter and setter method.

Conversely, your second snippet does compile because in this case, covariance isn't a problem - there's no setter in the base class (F) to be overriden, so the "weirdness" I described above isn't possible.

Upvotes: 4

Related Questions