Default implementation in interface in multiplatform project

For example I want to define an interface:
In commonMain:

expect interface Test {
    fun test(a: Other1): Other2
}

In jvmMain:

actual interface Test {
    @JvmDefault
    fun test(a: Other1): Other2 {
        ...
    }
}

But the compiler will say

Actual class 'Test' has no corresponding members for expected class members:

    public abstract expect fun test(a: Other1): Other2

    The following declaration is incompatible because modality is different:
        public open actual fun test(a: Other1): Other2

I can’t find any way to allow default implementation in the actual interface.

1 Like

If you want implement the func ‘test’ you can declare extending his functions on common like this

expect interface Test
expect fun Test.test(a: Other1): Other2

And on Jvm

actual fun Test.test(a: Other1) : Other2 {}
1 Like

The solution is to add the @JvmDefault annotation to the expect clause. The standard library has been updated to ignore this annotation on non-jvm platforms.

1 Like

No, the JvmDefault annotation is only supported on the JVM platform.

You can see the document only show a green point (meaning only supported on JVM) for the JvmDefault annotation.

I have also try to write an expect annotation and on JVM platform make it a typealias of JvmDefault, and use this annotation for the default implementation of an interface. But this does not help at all. The compiler still say the “modality is different”.

Did you ever try the solution you provided?

In my situation, I have to ensure that test is a default implementation in the interface Test.

With your solution, if someone want to use the JAR you build in Java, he / she has to import a class like TestImpl and use TestImpl.test instead of just implementing the interface Test.