Generic function in interface to return concrete implementation

4.8k views Asked by At

To an interface, I want to add a function that returns an object of the concrete implementation.

So with the interface:

interface Content {
        fun <???> cloneMe(): ?
}

and the classes

class Music: Content
class Video: Content

the function cloneMe() of the Music class should return a Music object and the the function cloneMe() of the Video class should return a Video object.

The closest I've come is:

interface Content {
    fun <T: Content> cloneMe(): T
}

class Music : Content {
    override fun <T : Content> cloneMe(): T {
        return Music() as T
    }
}

then I can do

val music: Music = Music().cloneMe<Music>()

The problem here is that I have to do an unchecked cast, which 'allows me' (i.e. will compile) to do

class Music : Content {
        override fun <T : Content> cloneMe(): T {
            return Video() as T
        }
}

which is problematic.

What's the best way to achieve this?

2

There are 2 answers

0
hotkey On BEST ANSWER

Typically this is done by parameterizing the Content interface as well, as follows:

interface Content<T : Content<T>> {
    fun cloneMe(): T
}

And the implementation:

class Music : Content<Music> {
    override fun cloneMe(): Music {
        return Music()
    }
}
5
tynn On

What you're trying to achieve is not necessary related to any Generics. Instead you could just use the type directly and implement a more detailed override.

interface Content {
    fun cloneMe(): Content
}

class Music : Content {
    override fun cloneMe() = Music()
}