Force use of extension function when subtype has conflicting member function

Hello,

I have the following scenario:

  • interface A
  • interface B : A
  • extension fun A.foo()
  • member fun foo() on B
  • bar: B

I wanna call the A.foo on bar instead of B#foo. According to this documentation article, the member function always wins, but I was wondering if there was a way to force the extension function to be called, by using FQN or something like that.

My concrete case is using Redisson in a Kotlin coroutines project. I know there is the kreds library, but it is still very young and not suitable for what I’m working on right now. Redisson uses its RFuture which derives from Java’s own java.util.concurrent.Future, for which kotlinx-coroutines-future provides an await() extension method.

If it’s utterly impossible to do what I want, I suppose I can use their reactive streams client and use kotlinx-coroutines-reactive (which from what I can see does not suffer from this conflicting issue), but I’d rather use Redisson’s Future-based client.

Thanks in advance!

If the static type of the expression is A, then the extension will be picked. You can achieve that by explicitly declaring the type:

interface A
interface B: A {
    fun foo()
}
class BImpl: B {
    override fun foo() {
        println("Member called")
    }
}
fun A.foo() {
    println("Extension called")
}

fun main() {
    val a: A = BImpl()
    a.foo()
}

Alternatively, you can create an alias:

import foo as foo_extension

bar.foo_extension()
2 Likes

Aaah, I see, that makes sense. In this case, though, I think it’s better to
go with the alias rather than the explicit super interface, since I’d be
doing stuff like topic.publishAsync(...).await(), and putting
publishAsync’s result onto a variable to then call .await on would be a
bit cumbersome.

Thank you both for your replies! :3