elect
elect

Reputation: 7190

Kotlin, instantiation issue and generic

I have a class Vec3i that extends Vec3t

data class Vec3i(
  override var x: Int = 0,
  override var y: Int = 0,
  override var z: Int = 0
) : Vec3t(x, y, z)

that has as one secondary constructor as follow

constructor(v: Vec3t<Number>) : this(v.x.toInt(), v.y.toInt(), v.z.toInt())

and another class Vec3ub that extends always Vec3t

data class Vec3ub(
  override var x: Ubyte = Ubyte(0),
  override var y: Ubyte = Ubyte(0), 
  override var z: Ubyte = Ubyte(0)
) : Vec3t(x, y, z)

Where Vec3t is in turn

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

And Ubyte extends Number

I'd like to instantiate a Vec3i from a Vec3ub

Vec3i(vec3ub)

but the compilers complains that there is no constructor for that..

why isn't valid the secondary constructor I quoted previously?

Upvotes: 0

Views: 95

Answers (1)

nhaarman
nhaarman

Reputation: 100388

For completeness, as stated in my comment, the following compiles correctly:

data class Vec3i(
        override var x: Int = 0,
        override var y: Int = 0,
        override var z: Int = 0
) : Vec3t<Int>(x, y, z) {

    constructor(v: Vec3t<out Number>) : this(v.x.toInt(), v.y.toInt(), v.z.toInt())
}

data class Vec3ub(
        override var x: Ubyte,
        override var y: Ubyte,
        override var z: Ubyte
) : Vec3t<Ubyte>(x, y, z)

abstract class Vec3t<T>(
        override var x: T,
        override var y: T,
        open var z: T
) : Vec2t<T>(x, y)

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

fun test(vec3ub: Vec3ub) {
    val vec3i = Vec3i(vec3ub)
}

abstract class Ubyte : Number() 

Note the constructor(v : Vec3t<out Number>) : ... and all other added generic parameter types. Vec3t<out Number> is necessary instead of just Vec3t<Number> here since you don't pass a Number, but rather a subclass of it.

Upvotes: 2

Related Questions