简体   繁体   中英

Interface with generic type of the class implementing the interface?

Having a class that implement a interface with generic type of "This" class

Is there a way to do this without a cast?

Simple code:

interface Triggerable<This: Triggerable<This>> {
    var trigger: (This) -> Unit
    fun triggerNow() = trigger(this as This)
}
class Test : Triggerable<Test>{
    override var trigger: (Test) -> Unit = { /*...*/ }
}

The same a little more complex:

interface TriggerInterface<T> {
    val trigger: (T) -> Unit
    fun triggerNow()
}
interface Triggerable<T: Triggerable<T>>: TriggerInterface<T> {
    override fun triggerNow() = trigger(this as T)
}
interface Signalable<T>: TriggerInterface<T> {
    var value: T
    override fun triggerNow() = trigger(value)
}
class Test : Triggerable<Test>{
    override val trigger: (Test) -> Unit = { /*...*/ }
}

Should be possible like this

 interface TriggerInterface<T: TriggerInterface<T>> {
    val trigger: (T) -> Unit
    fun triggerNow()

    fun getThis(): T
 }

 interface Triggerable<T: TriggerInterface<T>>: TriggerInterface<T> {
     override fun triggerNow() = trigger(getThis())
 }

 class Test : Triggerable<Test>{
     override fun getThis(): Test = this

     override val trigger: (Test) -> Unit = { /*...*/ }
 }

Check http://www.angelikalanger.com/GenericsFAQ/FAQSections/ProgrammingIdioms.html#FAQ206

I would also personally recommend to reconsider if you really need both TriggerInterface AND Triggerable (where one inherits from the other).

Calling override fun triggerNow() = trigger(this as T) you are trying to cast Triggerable<T> to T thats why compiler warns you about unchecked cast

having

    val trigger: (TriggerInterface<T>) -> Unit

will allow you to call trigger with no casting

    override fun triggerNow() = trigger(this)

to actually execute

override val trigger: (Test) -> Unit = { /*...*/ }

you need an instance of Test to pass inside of trigger which is not declared anywhere in your code yet

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM