Yann Armelin
Yann Armelin

Reputation: 711

Overriding generic function using sub-class type parameter

I have the following interface in kotlin, not modifiable because it's defined in a third party library. And I would like to override the generic method using a type parameter of the subclass:

interface Factory {
    fun <T> create(modelClass: Class<T>): T
}


// The naive solution doesn't compile :  "Class is not abstract and does not implement abstract member":
class ConcreteFactory1 <T> (val creator: () -> T) : Factory {
    override fun create(modelClass: Class<T>): T {
        return creator()
    }
}


// If we introduce a second type parameter, it compiles, but generates a "Unchecked Cast" warning:
class ConcreteFactory2 <T> (val creator: () -> T) : Factory {
    override fun <T2> create(modelClass: Class<T2>): T2 {
        return creator() as T2
    }
}

Is there a way to achieve this without compilation warning ?

Upvotes: 3

Views: 463

Answers (1)

al3c
al3c

Reputation: 1452

It depends. That interface requires that you're able to handle any possbile Class<T> and your implementation doesn't.

So the question is what do you want to do when create is called with a type which is not the one your ConcreteFactory2 can create?

If the only thing you want is not to see the unchecked cast you can do this:

class ConcreteFactory2 <T> (val creator: () -> T) : Factory {
    override fun <T2> create(modelClass: Class<T2>): T2 {
        return creator() as? T2 ?: throw IllegalArgumentException("unsupported type")
    }
}

But whether that is an acceptable implementation of that interface really depends on how is that used.

Upvotes: 1

Related Questions