我即将使用LibGDX写一个2D游戏,它有很好的类Vector2
。
由于我以功能性的方式写作(复制,模式匹配等),我希望它能成为一个案例类。
因为它不是一个,所以我决定尝试扩展它而没有成功:
import com.badlogic.gdx
class Vector2(x: Float, y: Float) extends gdx.math.Vector2(x, y) {
def copy(x: Float = this.x, y: Float = this.y): Vector2 = {
new Vector2(x, y)
}
}
object Vector2 {
def apply(x: Float = 0, y: Float = 0): Vector2 = {
new Vector2(x, y)
}
}
问题是以下内容会引发println(Vector2(1, 2).x)
,因为没有x
字段。
如果我像class Vector2(override val x: Float, override val y: Float)
那样写它会抛出:
在Float类型的Vector2类中覆盖变量x;值x有 不兼容的类型类Vector2(覆盖val x:Float, override val y:Float)扩展gdx.math.Vector2(x,y){
我无法让这个工作。我还尝试var
而java.lang.Float
没有成功。
编辑:似乎不可能,因为Scala生成了一个函数,并且Java代码中没有相应的函数。
答案 0 :(得分:2)
您正在隐藏您想要的x
。
人们常常因为需要重命名类参数以避免创建字段而烦恼。
请参阅this symptom和the shadowing issue。
在这种情况下,它会导致互操作问题。
scala> :pa
// Entering paste mode (ctrl-D to finish)
class Vector2(x0: Float, y0: Float) extends gdx.math.Vector2(x0, y0) {
def copy(x: Float = this.x, y: Float = this.y): Vector2 = {
new Vector2(x, y)
}
}
object Vector2 {
def apply(x: Float = 0, y: Float = 0): Vector2 = {
new Vector2(x, y)
}
}
// Exiting paste mode, now interpreting.
defined class Vector2
defined object Vector2
scala> Vector2(1, 2).x
res1: Float = 1.0
脚注:
前,
scala> Vector2(1, 2).x
java.lang.IllegalAccessError: tried to access field Vector2.x from class
... 40 elided
因为this.x
在子类中创建了一个私有字段。
错误的表达不应该试图访问该字段;如果没有访问者x
,它应该
scala> (Vector2(1,2): gdx.math.Vector2).x
res2: Float = 1.0
您无法绕过super.x
的阴影,因为它不是def
。
答案 1 :(得分:0)
我尝试了很多东西,看起来你在编辑中得出的结论是正确的。
然而,有一种更迂回的方式来完成这项工作:
package rrs.scribble
import com.badlogic.gdx.math
class Vector2(x: Float, y: Float) {
val gdxV2 = new math.Vector2(x, y)
}
object Vector2 {
implicit class V2(v2: Vector2)
extends math.Vector2(v2.gdxV2)
}
object Demo {
import Vector2._
def main(args: Array[String]) {
val v2a = new Vector2(12.34f, 56.78f)
val v2b = new Vector2(12.345f, 56.789f)
println(s"v2=$v2a; v2=$v2a; sum=${v2a.add(v2b)}")
println(s"(v2a =E(0.01) v2b)=${v2a.epsilonEquals(v2b, 0.01f)}")
println(s"(v2a =E(0.001) v2b)=${v2a.epsilonEquals(v2b, 0.001f)}")
// Note: This won't compile, apparently because
// hasOppositeDirection is inherited not implemented within Vector2
// println(s" v2 = $ v2a; sum = $ sumA; hasOppositeDirection = $ {v2.hasOppositeDirection}") } }
运行此产生:
scala> rrs.scribble.Demo.main(Array[String]())
v2=rrs.scribble.Vector2@6e8d0165; v2=rrs.scribble.Vector2@6e8d0165; sum=[24.685001:113.569]
(v2a =E(0.01) v2b)=true
(v2a =E(0.001) v2b)=false
不幸的是,正如评论所指出的那样,Vector2继承的方法似乎失败了。实际上,我不确定为什么会这样。然而,这种方法还有一个优点。例如,您可以在+
上定义-
,V2
等,以增强基础gdx.math.Vector2
的可用性。