我很难为这个我要组装的类层次结构制作解决方案。我有一个抽象的数据包“Vertex”,以及一个在Vertex实例上运行的抽象类“VertexShader”。事实上,VertexShader的派生类在特定的Vertex派生类上运行。它很像带有def eat(f : Food)
的Animal类的经典示例,但其子类只能吃特定种类的食物。
我想问题是派生的Vertex类应该提供一个对顶点进行操作的函数“+”,我需要将这个操作的结果传递给VertexShader。问题是系统不允许我将'+'操作的结果传递给VertexShader对象,即使这些类型都通过推理正确解析。
非常欢迎任何关于如何重新设计以避免类型问题的建议。
/// Abstract Interface Types
trait Vertex
{
type V <: Vertex
def position : Float
def + (v : V) : V
}
/// Derived class of vertex shader will use a specific derived class of
/// vertex that it can shade
trait VertexShader
{
type V <: Vertex
def shade( v : V ) : Float
}
/// Concrete Implementation Example
class MyVertex(p : Float, c : Float) extends Vertex
{
type V = MyVertex
val position : Float = p // inherited
val color : Float = p*2.0f // custom
def + (v : MyVertex) : MyVertex = new MyVertex(position + v.position, color + v.color)
}
class MyVertexShader extends VertexShader
{
type V = MyVertex
def shade( v : MyVertex ) : Float = v.position + v.color
}
object Bootstrap
{
def main ( args : Array[String] )
{
/// Vertex and vertex shader, pretend concrete class type is unknown
/// as these objects will be pulled out of some other abstract object
/// interface at runtime
val mVShader : VertexShader = new MyVertexShader
val mV0 : Vertex = new MyVertex(1.0f, 9.0f)
/////////////////////////////////////////
val shadeValue = mVShader.shade(mV0 + mV0)
}
}
答案 0 :(得分:6)
问题是您的类型注释正在丢弃信息:
val mVShader : VertexShader = new MyVertexShader
你刚才说它是VertexShader
- 但是按顺序排列
要将MyVertex
传递给它的阴影方法,你需要更多
具体:
val mVShader : VertexShader {type V = MyVertex} = new MyVertexShader
最简单,最简洁的解决方法是删除类型注释:
val mVShader = new MyVertexShader
val mV0 = new MyVertex(1.0f, 9.0f)
回复您的评论:
如果你有
trait Mesh {
trait T <: Vertex
def getVertex: T
}
和
class AMash extends Mesh { ... }
您可以将T
的具体AMesh
视为
AMesh#T
和特定的AMash
对象
val amesh: AMesh = ...
... amesh.T ...
虽然后者是一件棘手的事情,但并不总是有效,或者需要dependent method types。