Kotlin和泛型,用泛型数组实现抽象泛型类

时间:2016-11-10 13:24:26

标签: arrays generics kotlin

我有以下抽象类

abstract class Vec2t<T : Number>(open var x: T, open var y: T)

实施

data class Vec2(override var x: Float, override var y: Float) : Vec2t<Float>(x, y)

到目前为止,一切正常

现在,我想为矩阵做类似的事情,这是我的抽象类

abstract class Mat2t<T : Number>(open var value: Array<out Vec2t<T>>)

应由

实施

class Mat2(override var value: Array<Vec2>) : Mat2t<Float>(value)

但编译器抱怨Array<Vec2>

  

错误:(8,32)Kotlin:'value'的类型与重写的var-property'public open var value:Array&gt;的类型不匹配。在main.mat.Mat2t'

中定义

我被告知:

  • 当我覆盖它时,我无法更改var属性的类型(但实际上我并没有真正改变它,我用一个子类型覆盖它...是同样的事情吗?)
  • mat2.value = object : Vec2t<Float>() { ... }无效,Mat2t<Float>
  • 的任何子类都不一定如此

我如何克服这些问题?

有没有办法让一个带有通用数组的抽象泛型类Mat2t并用子类型数组实现它?

1 个答案:

答案 0 :(得分:3)

您可以通过将通用参数设为Vec2t的子类型而不是Vec2t的通用参数类型(T : Number)的子类型来实现此目的:

abstract class Mat2t<T : Vec2t<*>>(open var value: List<T>)

class Mat2(override var value: List<Vec2>) : Mat2t<Vec2>(value)

请注意,当您重写var value时,您不需要在抽象类构造函数中使用它。这同样适用于Vec2t。 e.g:

abstract class Vec2t<T : Number> {
    abstract var x: T
    abstract var y: T
}

class Vec2(override var x: Float, override var y: Float) : Vec2t<Float>()

abstract class Mat2t<T : Vec2t<*>> {
    abstract var value: List<T>
}

class Mat2(override var value: List<Vec2>) : Mat2t<Vec2>()

如果适合你,这些抽象类甚至可以表示为接口:

interface Vec2t<T : Number> {
    var x: T
    var y: T
}

data class Vec2(override var x: Float, override var y: Float) : Vec2t<Float>

interface Mat2t<T : Vec2t<*>> {
    var value: List<T>
}

data class Mat2(override var value: List<Vec2>) : Mat2t<Vec2>