How to override Any parameter in Kotlin with Java Object?

Viewed 136

I'm writing a retrofit implementation and I have the following interface method:

suspend fun uploadAvatar(file: Any, sessionToken: String)

In my impelementation I'm trying to override the 'file' parameter as a MultipartBody.Part object:

override suspend fun uploadAvatar(file: MultipartBody.Part, sessionToken: String)

and I'm getting the following error:

error message

I can see that okhttp3 is written in Java and I'm assuming that's the reason for the error. If so how do I get around it? Otherwise what else could be going on?

1 Answers

It's not because it's written in Java. It's because you're trying to violate the interface contract by narrowing the type of an input parameter. The interface declares that file can be anything because it is of type Any. If the compiler let you narrow a type definition, then your class would be able to call functions specific to MultipartBody.Part on file, but then pass an instance of your class as the interface type, and some other code could pass a different class type to your function as file, which doesn't make sense.

I can't suggest how to avoid this problem because you didn't say how you're using your interface. I don't see what it really has to do with Retrofit.

In general, this kind of problem might be solved using generics, but that would only apply to some use cases. Example:

interface Foo<in T> {
    suspend fun uploadAvatar(file: T, sessionToken: String)
}

class MyFooBodyImpl: Foo<MultipartBody.Part> {
    suspend fun uploadAvatar(file: MultipartBody.Part, sessionToken: String) {
        TODO()
    }
}
Related