Add Scala operators to final Java class

final, java, operator-keyword, overloading, scala

Solution

Or is there maybe a Scala syntax that I don't know of to do these kinds of things?

Yeah, there are implicits:

class VectorMath(f: Float) { def * (v: Vector3f) = v mult f }
implicit def VectorMath(f: Float) = new VectorMath(f)

val v = new Vector3f(1,2,3)
1.2F * v
// treated as: VectorMath(1.2F).*(v)

Since Scala 2.10 the implicit conversion can also be written as:

implicit class VectorMath(f: Float) { def * (v: Vector3f) = v mult f }

Since 2.10 there are also value classes which are optimized by the compiler to get better performance:

implicit class VectorMath(val f: Float) extends AnyVal { def * (v: Vector3f) = v mult f }

Problem

I am using the jMonkeyEngine (Java Game Engine) in Scala, which works out pretty well so far, but now I am asking myself whether there is an elegant way of overloading operators for the `Vector3f` (and similar) classes. My first idea was to inherit from `Vector3f` and overload the operators, but `Vector3f` is final, so that is not an option. Next I thought maybe I could have a singleton/scala object with static methods that operate on `Vector3f`, like below, but that does not work either: ``` object VectorMath { def *(factor: Float, vector: Vector3f) = vector.mult(factor) } //and then somewhere import VectorMath._ var v = new Vector3f(1,2,3); var u = 1.2f * v; //this does not work, because Float does not have * overloaded for Vector3f var u = VectorMath.*(1.2f, v); //this does work, but defeats the purpose ``` So all I can think of now is to wrap the Vector3f in a new Scala class and delegate the operator calls to the appropriate Java methods. This has, however, three downsides: - I will have to do to a lot of back and forth conversions (a `toVector3f` and a `fromVector3f` method or something like that). - This problem becomes even worse when I have arrays of Vector3f/ScalaVectors. Since the classes are not related (except by composition), I would have to manually cast every element of the array every time I call a method in jME. - Even then I know of no way to overload an operator for my new ScalaVector class in such a way that I could have the factor in front, i.e. `1.2f * v`. My question: Can someone think of a way to make this more natural/elegant? How do you tackle similar problems? Or is there maybe a Scala syntax that I don know of to do these kinds of things? In C++ I would make a global operator that takes float and Vector3f as arguments and possibly friend it. Whats the Scala way to do this, or is that simply not possible?

Original source