1

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 = { /*...*/ }
}

2 Answers 2

3

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).

Sign up to request clarification or add additional context in comments.

2 Comments

It's needed because there is another interface which trigger another value
I accepted your answer because it's the best solution but not what I'm looking for. I ended using cast, because if the generic type argument "This" is well defined there will be no problem
0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.