【问题标题】:Kotlin and generics, implementing abstract generic class with generic arrayKotlin 和泛型,用泛型数组实现抽象泛型类
【发布时间】:2016-11-10 13:24:25
【问题描述】:

我有以下抽象类

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>:

Error:(8, 32) Kotlin: Type of 'value' doesn't match the type of the type of the overridden var-property 'public open var value: Array> defined in main.mat.Mat2t'

有人告诉我:

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

我该如何克服这些问题?

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

【问题讨论】:

    标签: arrays generics kotlin


    【解决方案1】:

    您可以通过使泛型参数成为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>
    

    【讨论】:

    • 它有效,很好。我看到你使用了List 而不是Array,有什么具体原因吗?获得协方差?作为参考,我正在尝试做一个this 的端口。关于界面的酷提示,+1
    • @elect 习惯我想。我几乎从不使用Array。另外,我看到您的Vec2data class,这使我相信您可能希望Mat2 也成为data class,在这种情况下,您必须自己覆盖equalshashCode,如果您使用Array(它没有实现它们)但是使用 List 编译器会为您处理它。另请参阅stackoverflow.com/q/36262305/3255152
    • 仅供参考:我不确定您到底在追求什么,但那里有各种线性代数/矩阵 Java 库:stackoverflow.com/questions/10815518/java-matrix-libraries。也许其中之一已经满足您的用例;也许不吧。享受吧!
    • 只是一个 kotlin glm 移植
    猜你喜欢
    • 2020-05-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-10
    • 2018-10-29
    相关资源
    最近更新 更多