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