我想要一个通用的向量抽象类/特征来指定某些方法,例如:
trait Vec
{
def +(v:Vec):Vec
def *(d:Double):Vec
def dot(v:Vec):Double
def norm:Double
}
我要
Vec2D和
Vec3D延长
Vec :
class Vec2D extends Vec { /* implementation */ }
class Vec3D extends Vec { /* implementation */ }
但是,例如,我如何才能做到
Vec2D只能添加到其他
Vec2D而不是
Vec3D ?
现在我只是在实现
Vec2D和
Vec3D没有共同点
Vec祖先,但这会因重复代码而变得乏味。我必须实现所有依赖于这些类的几何类(例如
Triangle 、
Polygon 、
Mesh 、...)两次,一次用于
Vec2D再次为
Vec3D .
我看到了 java 实现:
javax.vecmath.Vector2d和
javax.vecmath.Vector3d没有共同的祖先。这是什么原因?有没有办法在scala中克服它?
请您参考如下方法:
您可以使用 self 类型:
trait Vec[T] { self:T =>
def +(v:T):T
def *(d:Double):T
def dot(v:T):Double
def norm:Double
}
class Vec2D extends Vec[Vec2D] { /* implementation */ }
class Vec3D extends Vec[Vec3D] { /* implementation */ }
但是如果两个实现非常相似,您也可以尝试对 Dimension 进行抽象。
sealed trait Dimension
case object Dim2D extends Dimension
case object Dim3D extends Dimension
sealed abstract class Vec[D <: Dimension](val data: Array[Double]) {
def +(v:Vec[D]):Vec[D] = ...
def *(d:Double):Vec[D] = ...
def dot(v:Vec[D]):Double = ...
def norm:Double = math.sqrt(data.map(x => x*x).sum)
}
class Vec2D(x:Double, y:Double) extends Vec[Dim2D.type](Array(x,y))
class Vec3D(x:Double, y:Double, z:Double) extends Vec[Dim3D.type](Array(x,y,z))
当然,这取决于您希望如何表示数据,以及您是否希望拥有可变或不可变实例。对于“现实世界”应用程序,您应该考虑 http://code.google.com/p/simplex3d/




