I have a class a bit like this: ```class Vector(va...
# announcements
m
I have a class a bit like this:
Copy code
class Vector(val x: Double, val y: Double, val z: Double = .0) {
    operator fun div(n: Double) =
        Vector(x / n, y / n, z / n)

    fun magnitude() = sqrt(x*x + y*y + z*z)

    fun normalized() = when (val m = magnitude()) {
        0.0 -> Vector(x, y, z)
        else -> this / m
    }

    // more stuff
}
and I want to have another class with most of the same functionality, but more like as a wrapper, where
x
and
y
are
Int
but everything else is computed with `Double`s, and with 2 additional
Int
properties
targetX
and
targetY
. Is there anything in Kotlin that can help me achieve this without writing every method that wraps another method? (or any good idea?) I tried using`by` with an interface to delegate but the types (
Int
and
Double
) wouldn't match so it wouldn't work.
e
unfortunately you can't write code generic across different Number subtypes - there's no generic arithmetic operations, they're only defined on specific types. (as inherited from Java)
n
I've encountered this before and it's a major feels bad man
m
understood
okay thanks
y
Well actually it is possible but it might seem a bit complicated at first:
Copy code
abstract class Vector<N: Number>(val x: N, val y: N, val z: Double = .0) {
    operator fun div(n: Double) =
        createInstance(convertDoubleToDesiredNumber(x.toDouble() / n), convertDoubleToDesiredNumber(y.toDouble() / n), z / n)
    fun magnitude() = sqrt(convertDoubleToDesiredNumber(x.toDouble()*x.toDouble()).toDouble() + convertDoubleToDesiredNumber(y.toDouble()*y.toDouble()).toDouble() + z*z)
    fun normalized() = when (val m = magnitude()) {
        0.0 -> createInstance(x, y, z)
        else -> this / m
    }
    //I'm assuming that this is basically what you're trying to achieve
    abstract fun convertDoubleToDesiredNumber(d: Double): N
    abstract fun createInstance(x:N, y:N, z: Double): Vector<N>
    // more stuff
}

class DoubleVector(x: Double, y: Double, z: Double): Vector<Double>(x, y, z) {
    override fun convertDoubleToDesiredNumber(d: Double) = d
    override fun createInstance(x: Double, y: Double, z: Double) = DoubleVector(x, y, z)
}

class IntVector(x: Int, y: Int, z: Double, val targetX: Int, val targetY: Int): Vector<Int>(x, y, z) {
    override fun convertDoubleToDesiredNumber(d: Double) = d.toInt()
    override fun createInstance(x: Int, y: Int, z: Double) = IntVector(x, y, z, targetX, targetY)
}
Please note that because this works on generic `Number`s, it actually boxes the passed in Ints and Doubles, which might cause a performance impact.
e
right, you could do that yourself, but in addition to boxing which is quite impactful for numeric code, that pattern also runs into Kotlin's lack of self types