Herencia genérica de Kotlin – No coincide con el tipo

Estoy tratando de crear un set de proveedores para objects de reino. Aquí hay una estructura de ejemplo que he intentado build:

Interfaz:

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

Clase de proveedor base con function complementaria para instanciación de proveedor tipado:

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

Y aquí hay una class para niños:

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

El problema que tengo está en juego

 return SomeChildProviderProvider(context) 

Escriba desajuste. Obligatorio: E. Found: SomeChildProvider.

No puedo entender por qué no ve que E es en realidad SomeChildProvider. Gracias.

PD. Sé que puedo lanzarlo a E, pero en mi opinión, no debería ser necesario en esta situación. Tal vez me esté perdiendo algo obvio aquí o probablemente carezca de conocimiento de Kotlin.

ACTUALIZACIÓN1: después de la primera respuesta, nos hemos dado count de que el código anterior no tiene mucho sentido ya que tenemos que definir un tipo de proveedor que regresa y pasarlo al método de creación. La idea inicial fue que create method devuelve algún tipo que sea el subtipo BaseProvider. Aquí están los cambios que he hecho para apoyar la idea inicial:

IDataProvider

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

BaseProvider

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

ChildProvider

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

Llamada de UI

 BaseProvider.create(context).execute(realm) 

Aunque el método createModel devuelve RealmObject, su instancia será de ChildRealmModel. Lo que no me gusta de esto es que tenemos que inspeccionar el tipo de instancia y enviarlo si necesitamos el model exacto en otro lugar.

Tu código no es consistente.

En la statement de la function, se compromete a devolver E , que es un subtipo de BaseProvider<T> y puede ser elegido por el usuario en el sitio de la llamada.

Pero en la implementación, usted devuelve SomeChildProviderProvider , que por supuesto es un subtipo de BaseProvider<T> , pero aún puede no estar totalmente relacionado con E que fue elegido por el usuario.

Un ejemplo:

 class AnotherChildProvider : BaseProvider<ChildRealmModel>(context) {...} val x = BaseProvider.create<ChildRealmModel, AnotherChildProvider>(context) 

¿Cuál es el tipo de x ? De acuerdo con la firma de la function, debe ser AnotherChildProvider . Pero dentro de la function, devuelve SomeChildProviderProvider , que NO PUEDE ser AnotherChildProviderProvider a AnotherChildProviderProvider .

  • Tratando de entender el ejemplo de Kotlin
  • Usar Glide para almacenar imágenes de la vista web en caching
  • Llamada asincrónica para cada elemento dentro de una colección
  • Método igual para class de datos en kotlin
  • Enviar un resultado calculado previamente de una actividad de Kotlin a una vista de text en otro
  • cómo usar kapt en Android
  • Notificación Acción no disparando PendingIntent
  • ¿Cómo puedo enmascarar una contraseña con Anko?
  • En la progtwigción reactiva de Android, ¿cómo dividir los datos del object transmitido después de aplicar el filter?
  • ¿Se pueden usar corotines Kotlin "experimentales" en la producción?
  • Kotlin: function genérica como tipo de retorno?