Котлин и универсальные делегаты, как переключаться между подклассами

#generics #kotlin #delegates

#универсальные #kotlin #делегаты

Вопрос:

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

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

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

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

Комментарии:

1. Здесь есть A и B фактические имена классов или параметры? Если это реальные имена классов, то вам не нужно параметризовать свои подклассы с их помощью: DelegateForObjectA : Delegate<A> , не DelegateForObjectA<A> : Delegate<A> . (Не уверен, влияет ли это на основную проблему.)

2. хм, вы правы, это тип! код является DelegateForObjectA : Делегировать<A>

3. Какую ошибку это показывает?

Ответ №1:

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

 /**
 * 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" )
    }
}