Kotlin & Generic делегаты, как переключаться между подклассами - PullRequest
0 голосов
/ 27 марта 2019

У меня возникла проблема, и я хотел бы получить ваши отзывы об этом, особенно о том, как правильно обработать следующий случай:

У меня есть абстрактный класс, который определяет делегата:

abstract class Delegate<T: Any> {
    abstract fun bindData(item: T?)
}

И тогда у меня есть 2 реализации этого делегата:

class DelegateForObjectA: Delegate<A>() {
    var data: A? = null

    override fun bindData(item: A?){
        data = item
    }
}

class DelegateForObjectB: Delegate<B>() {
    var data: B? = null

    override fun bindData(item: B?) {
        data = item
    }
}

Я хочу иметь возможность переключаться между этими двумя делегатами на лету, что означает, что в моей деятельности у меня есть:

lateinit var delegate: ActionButtonsViewDelegate<*>
private var delegateA by lazy { DelegateForObjectA() }
private var delegateB by lazy { DelegateForObjectB() }

init {
    delegate = delegateA
}

А потом позже:

fun SwitchDelegateAndBindData(item: Any?) {
    if (item is B) {
        delegate = delegateB
    } else {
        delegate = delegateA
    }

    delegate.bindData(item)
}

Я пытался добиться этого с помощью входа / выхода, но безуспешно! Как я могу объявить свое свойство делегата для принятия обоих делегатов, не конфликтуя с типом?

1 Ответ

0 голосов
/ 27 марта 2019

Я нашел способ заставить его работать, хотя я не уверен точно, почему он работает и действительно ли он соответствует вашим потребностям ^^ '

/**
 * You can edit, run, and share this code. 
 * play.kotlinlang.org 
 */

fun main() {
    val a = A()
    val b = B()
    val test = Test()

    test.switchDelegate(a)
    test.switchDelegate(b)
    test.switchDelegate(a)
}

class Test {
    var delegate: Delegate<*>
    private val delegateA by lazy { DelegateForObjectA() }
    private val delegateB by lazy { DelegateForObjectB() }

    init {
        delegate = delegateA
    }

    fun switchDelegate(item: Any) {
        if (item is B) {
            delegate = delegateB
        } else {
            delegate = delegateA
        }
        delegate.bindData( item )
    }
}

abstract class Delegate<T> {
    abstract fun <T:Any> bindData(item : T)
}

class A {}

class B {}

class DelegateForObjectA: Delegate<A>() {
    override fun <A:Any> bindData(item: A){
        println( "Binding A" )
    }
}

class DelegateForObjectB: Delegate<B>() {
    override fun <B:Any> bindData(item: B) {
        println( "Binding B" )
    }
}
...