netimen
netimen

Reputation: 4427

Chained calls and inheritance

I have a following class hierarchy

open class B {
    fun b() = this
}

open class C : B() {
    fun c() = 0
}

and I would like to do something like this:

fun test(c: C) {
    c.b().c() // error: c.b() returns B, not C
}

I understand why such problem exists in Java, but Kotlin has smart casts, so why compiler can't smart cast c.b() to C in this situation?

Are there any workarounds better than the Java ones in Kotlin to make chained calls work correctly with inheritance?

Upvotes: 4

Views: 523

Answers (1)

voddan
voddan

Reputation: 33839

Smart cast is not applicable here, since compiler has no way to understand that B#b() returns an instance of C.

The fact that the returned B instance is a C is obvious for us, humans, but only after we see the implementation of the method. Type inference can only work with function signatures, so all it sees is fun b(): B = ...

A simple solution for your case would be to make b() a generic extension:

open class B 

fun <T: B> T.b() = this

open class C : B() {
    fun c() = 0
}

Upvotes: 8

Related Questions