微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用Kotlin构建具有通用数据类型的类

如何解决使用Kotlin构建具有通用数据类型的类

我正在构建自己的Kotlin和一般编程知识,并在尝试遵循良好做法的过程中。我正在一个具有一些重要矩阵操作的项目中,所以我决定自己构建自己的Matrix类并自己定义逻辑。

我可以将它构建为两个接受双打。但是我想构建它以支持任何数字类型,甚至允许我定义的其他类(如分数或复数)。

我还想将矩阵的值设为私有,以便仅通过特定方法访问值。主要是因为这似乎是将来处理安全数据项目的最佳实践。

问题:现在设置为界面。仍有改善的空间。我正在努力做的一件事是找到一种为接口提供参数的方法,该参数用于存储乘性标识(1)和一个用于每个类实现的加性标识(0)。由于某种原因,这似乎不起作用。

interface MyNumber<T> {
    operator fun plus(other: T): MyNumber<T>
    operator fun unaryMinus(): MyNumber<T>
    operator fun minus(other: T): MyNumber<T>
    operator fun times(other: T): MyNumber<T>
    operator fun div(other: T): MyNumber<T>
    operator fun compareto(other: T): Int

}

class MyInt(val value: Int): MyNumber<MyInt> {
    override fun plus(other: MyInt) = MyInt(value + other.value)
    override fun unaryMinus() = MyInt(-value)
    override fun minus(other: MyInt) = MyInt(value - other.value)
    override fun times(other: MyInt) = MyInt(value * other.value)
    override fun div(other: MyInt) = MyInt(value / other.value)
    override fun toString() = value.toString()
    override fun equals(other: Any?): Boolean {
        return when{
            other is MyInt -> value == other.value
            other is Int -> value == other
            else -> false
        }

    }
    override fun compareto(other: MyInt) = value.compareto(other.value)
}
class MyLong(val value: Long): MyNumber<MyLong> {
    override fun plus(other: MyLong) = MyLong(value + other.value)
    override fun unaryMinus() = MyLong(-value)
    override fun minus(other: MyLong) = MyLong(value - other.value)
    override fun times(other: MyLong) = MyLong(value * other.value)
    override fun div(other: MyLong) = MyLong(value / other.value)
    override fun toString() = value.toString()
    override fun equals(other: Any?): Boolean {
        return when{
            other is MyLong -> value == other.value
            other is Long -> value == other
            else -> false
        }

    }
    override fun compareto(other: MyLong) = value.compareto(other.value)
}
class MyDouble(val value: Double): MyNumber<MyDouble> {
    override fun plus(other: MyDouble) = MyDouble(value + other.value)
    override fun unaryMinus() = MyDouble(-value)
    override fun minus(other: MyDouble) = MyDouble(value - other.value)
    override fun times(other: MyDouble) = MyDouble(value * other.value)
    override fun div(other: MyDouble) = MyDouble(value / other.value)
    override fun toString() = value.toString()
    override fun equals(other: Any?): Boolean {
        return when{
            other is MyDouble -> value == other.value
            other is Double -> value == other
            else -> false
        }

    }
    override fun compareto(other: MyDouble) = value.compareto(other.value)
}
class Fraction private constructor(val num: Long,val div: Long): MyNumber<Fraction> {
    data class Builder(var numerator: Long = 0L,var divisor: Long = 1L) {
        fun build(numerator: Long,divisor: Long): Fraction {
            if (divisor == 0L) {throw ArithmeticException("Cannot divide by Zero")}
            this.numerator = numerator
            this.divisor = divisor
            val gcd = gcd(numerator,divisor)
            val sign = sign(divisor.todouble()).toLong()
            return Fraction(sign * numerator / gcd,sign * divisor / gcd)
        }
    }
    val value = num.todouble()/div
    override fun plus(other: Fraction) =
        Builder().build(num * other.div + div * other.num,div * other.div)
    override fun unaryMinus() = Fraction(-num,div)
    override fun minus(other: Fraction) = this + -other
    override fun times(other: Fraction) =
        Builder().build(num * other.num,div * other.div)
    fun invert() = Builder().build(div,num)
    override fun div(other: Fraction) = this * other.invert()
    override fun toString() = "$num / $div"
    override fun equals(other: Any?): Boolean {
        return when{
            other is Fraction -> num * other.div == div * other.num
            other is Double -> value == other
            else -> false
        }

    }
    override fun compareto(other: Fraction) = value.compareto(other.value)
}
class Complex(val real: Double,val image: Double): MyNumber<Complex> {
    val abs = sqrt(real * real + image * image)
    override fun plus(other: Complex) = Complex(real + other.real,image + other.image)
    override fun unaryMinus() = Complex(-real,-image)
    override fun minus(other: Complex) = this + -other
    operator fun times(scalar: Double) =
        Complex(real * scalar,image * scalar)
    operator fun div(scalar: Double) = this * (1/scalar)
    override fun times(other: Complex) =
        Complex(real * other.real - image * other.image,real * other.image + image * other.real)
    fun conj() = Complex(real,-image)
    fun invert() = this.conj() / (this * this.conj()).abs
    override fun div(other: Complex) = this * other.invert()
    override fun toString() = "$real + ${image} i"
    override fun equals(other: Any?): Boolean {
        return when{
            other is Complex -> real == other.real && image == other.image
            other is Double -> real == other && image == 0.0
            else -> false
        }
    }
    override fun compareto(other: Complex) = real.compareto(other.real)
}
@Suppress("UNCHECKED_CAST")
class Matrix<T: MyNumber<T>>(val width: Int,val height: Int,private val values: List<List<MyNumber<T>>>) {

    data class Builder(var width: Int = 0,var height: Int = 0) {

        fun parameters(width: Int,height: Int) {
            this.width = width
            this.height = height
        }
        fun <T: MyNumber<T>> build(data: List<T>): Matrix<T> {
            val values = List(height) { j -> List(width) {
                    i -> data[(j * width + i) % data.size]
            }}
            return Matrix(width,height,values)
        }
    }
    fun getRowOrNull(j: Int): List<MyNumber<T>>? {
        if (j in 0 until height) {
            return values[j]
        }
        return null
    }
    fun getIndexed(i: Int,j: Int): MyNumber<T> {
        return values[j][i]
    }
    fun getColOrNull(i: Int): List<MyNumber<T>>? {
        if (i in 0 until width) {
            return List(height) { j -> values[j][i]}
        }
        return null
    }
    operator fun plus(other: Matrix<T>): Matrix<T>? {
        if (width != other.width || height != other.height ) {
            return null
        }
        val newData = List(height) { j -> List(width) {
                i -> getIndexed(i,j).plus(other.getIndexed(i,j) as T)
        }}
        return Matrix(width,newData)
    }
    operator fun times(other: Matrix<T>): Matrix<T>? {
        if (width != other.height) {
            return null
        }
        val newData = List(height) { j -> List(other.width) {
                i -> values[j].mapIndexed { k,v -> (v * other.values[k][i] as T) }
            .reduce{acc,it -> acc + it as T }
        }}
        return Matrix(other.width,newData)
    }
    fun transpose(): Matrix<T> {
        val newData = List(width) { i -> List(height) {
                j -> values[j][i]
        }}
        return Matrix(height,width,newData)
    }
    fun getMinor(i: Int,j: Int): Matrix<T>? {
        if (i in 0 until width && j in 0 until height) {
            val newData = List(height - 1) { y ->
                List(width - 1) { x ->
                    when {
                        x < i && y < j -> values[y][x]
                        x < i -> values[y + 1][x]
                        y < j -> values[y][x + 1]
                        else -> values[y + 1][x + 1]
                    }
                }
            }
            return Matrix(width - 1,height - 1,newData)
        }
        return null
    }/*
    fun determinate(): T {

    }
    fun coFactor(i: Int,j: Int): T {
        sign = if ((i + j) % 2 == 0) 1
    }*/

    override fun toString(): String {
        var string = ""
        for (j in 0 until height) {
            string += getRowOrNull(j)?.toString() + "\n"
        }
        return string
    }
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。