Dolor de cabeza por inheritance genérica de Kotlin

Soy nuevo en Kotlin y estoy intentando comstackr este código sin éxito (este es solo un ejemplo de lo que quiero hacer en un proyecto real):

abstract class Builder<T: Any, Y: Any> class BuilderImpl() : Builder<String, Int>() abstract class Shape<T: Any>(){ abstract var builder: Builder<T, *> } class Circle() : Shape<String>(){ override var builder: Builder<String, Int> = BuilderImpl() } 

Quiero anular la propiedad del constructor de la class Shape en la class Circle. La class Shape solo conoce el primer tipo genérico de la class Builder. El segundo podría ser de cualquier tipo, entonces uso * para eso.

Cuando bash anular la propiedad del constructor en la class Circle, el comstackdor se queja con el post:

  "Var-property type is 'Builder<String, Int>', which is not a type of overriden public abstract var builder: Builder<String, *>". 

También he intentado con algo como "out any" en lugar de *, sin éxito.

No tengo ni idea de cómo get este código comstackdo.

Cuando anula una propiedad var , el comstackdor aplica esa

  • get el valor de la propiedad anulada es seguro para types: si la propiedad original tiene tipo S , la propiedad reemplazada debería devolver instancias de S , es decir, su tipo debe ser S o su subtipo (por ejemplo, es seguro devolver un Int cuando Number es requerido);

  • establecer el valor de la propiedad reemplazada es segura para types: si la propiedad original tiene tipo S , la propiedad reemplazada debería aceptar objects de S como su valor, por lo que su tipo debe ser S o algunos de sus supertypes (por ejemplo, si necesitamos almacenar una String , almacenarla como Any estaría bien)

Teniendo en count estos dos requisitos, el único tipo que puede tener una propiedad var invalidada es el propio tipo de propiedad original, porque sus subtypes y supertypes violarán una de las condiciones anteriores. Por ejemplo, la propiedad reemplazada todavía debería poder almacenar un Builder<T, *> y especificar su tipo para Builder<T, Int> no es una opción:

 val s: Shape<SomeType> = Circle<SomeType>() val b: Builder<SomeType, *> = someBuilder s.builder = b // should be type-safe, but won't be with the override you want to do 

Por lo tanto, simplemente no puede cambiar el tipo de una propiedad var cuando la reemplaza, porque, en términos de generics de Kotlin, está tanto in position de out como de out .

Sin embargo, puede probar una de las siguientes opciones:

  • Cambiar a una propiedad val . En este caso, no hay un segundo requisito, y puede cambiar el tipo de propiedad a un subtipo del tipo de propiedad original:

     abstract class Shape<T: Any>(){ abstract val builder: Builder<T, *> } class Circle() : Shape<String>(){ override var builder: Builder<String, Int> = BuilderImpl() // OK } 
  • Agregue un parámetro genérico y especifíquelo en la subclass. En este caso, podrá usar var , porque Circle será un subtipo de una especialización Shape<String, Int> , no el tipo original Shape<T, R> :

     abstract class Shape<T: Any, R: Any>(){ abstract var builder: Builder<T, R> } class Circle() : Shape<String, Int>(){ override var builder: Builder<String, Int> = BuilderImpl() // OK } 
  • Kotlin: ¿Qué es kotlin.String! tipo
  • Kotlin - No coincide el tipo: Obligatorio: Cadena, Encontrado: () -> Cadena
  • Forma correcta de inyectar Dagger 2 + Kotlin + ViewModel
  • Kotlin - Use Realm Module en android
  • ¿Referencia fuera de la class sellada en Kotlin?
  • Kotlin no puede usar 'esto' en init
  • ¿Puede el comstackdor de Kotlin optimizar las funciones de envoltura remota?
  • ¿Cómo crear una implementación anónima de una interfaz?
  • Android Studio 3.0 Kotlin no funciona correctamente
  • El service está creando una nueva instancia de mediaplayer
  • Kotlin android studio Intento cambiar el text del button pero obtengo el post "se espera un valor de tipo boolean"