Kotlin泛型继承-类型不匹配

巴吉古斯科

我正在尝试为领域对象构建一组提供程序。这是我尝试构建的示例结构:

界面:

interface IDataProvider<out T : RealmObject> {
     fun getRealmObject(): T
}

具有提供程序实例化提供程序实例的伴随功能的基本提供程序类:

open abstract class BaseProvider<out T : RealmObject> constructor(protected val context: Context?) : IDataProvider<T> {

     companion object {
         fun <T : RealmObject, E : BaseProvider<T>> create(context: Context?): E {        
        if (something) {
            return SomeChildProviderProvider(context)
        } else {
            throw TypeNotSupportedException()
        }
      }
    }
 }

这是一个儿童班:

class SomeChildProvider(context: Context?) : BaseProvider<ChildRealmModel>(context){
    override fun getRealmObject(): ChildRealmModel {
         throw UnsupportedOperationException("not implemented")
    }
}

我的问题就在网上

return SomeChildProviderProvider(context)

类型不匹配。必需:E.找到:SomeChildProvider。

我不知道为什么它没有看到E实际上是SomeChildProvider。谢谢你。

PS我知道我可以将其转换为E,但是在我看来,在这种情况下不需要使用它。也许我在这里缺少明显的东西,或者可能缺少Kotlin知识。

UPDATE1:在第一个答案之后,我们已经意识到上面的代码没有多大意义,因为我们必须定义一个返回提供程序的类型并将其传递给create方法。最初的想法是create方法返回某种类型的类型,该类型是BaseProvider子类型。以下是为了支持最初的想法而进行的更改:

IDataProvider

interface IDataProvider {
    fun execute(realm: Realm)
    fun createModel(realm: Realm): RealmObject
}

基本提供者

 open abstract class BaseProvider constructor(protected val context: Context?) : IDataProvider {

    override fun execute(realm: Realm) {
        realm.executeTransaction { r ->
            createModel(r)
        }
    }

    companion object {
        fun create(context: Context?): IDataProvider {
            if (something) {
                return ChildProvider(context)
            } else {
                throw TypeNotSupportedException()
            }
        }
    }
}

儿童提供者

class ChildProvider(context: Context?) : BaseProvider(context) {
    override fun createModel(realm: Realm): ChildRealmModel {
        var realmObject = realm.createObject(ChildRealmModel ::class.java)
        //object property initialization
        return realmObject
    }
}

用户界面调用

BaseProvider.create(context).execute(realm)

尽管createModel方法返回RealmObject,但它的实例将是ChildRealmModel。我不喜欢的是,如果我们在其他地方需要精确的模型,则必须检查实例类型并转换为实例。

沃丹

您的代码不一致。

在函数声明中,您保证要返回E,这是的子类型,BaseProvider<T>可以由用户在调用站点上选择。

但是在实现中,您返回SomeChildProviderProvider,这当然是的子类型BaseProvider<T>,但仍然可能与E用户选择的类型完全无关

一个例子:

class AnotherChildProvider : BaseProvider<ChildRealmModel>(context) {...}

val x = BaseProvider.create<ChildRealmModel, AnotherChildProvider>(context)

是什么类型的x根据功能签名,必须为AnotherChildProvider但是在函数内部,您SomeChildProviderProvider不能将其强制转换AnotherChildProviderProvider

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章