首页 文章

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

提问于
浏览
1

我有以下抽象类

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'的类型与在main.mat.Mat2t中定义的重写的var-property'public open var value:Array>的类型不匹配'

有人告诉我:

  • 当我覆盖它时,我无法更改 var 属性的类型(但实际上我并没有真正改变它,我用一个子类型覆盖它...是同样的事情吗?)

  • mat2.value = object : Vec2t<Float>() { ... } 无效, Mat2t<Float> 的任何子类都不一定如此

我怎么能克服这些问题呢?

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

1 回答

  • 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 . 例如 . :

    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>
    

相关问题