基本上我想做这样的事情:
class Shape
class CoordSystem
class C3D(val x: Double, y: Double, z: Double) extends CoordSystem
class C2D(val x: Double, y: Double) extends CoordSystem
abstract class Shape {
def getCoords[C <: CoordSystem]: List[C]
}
class Pyramid extends Shape {
def getCoords: List[C3D] =
List(new C3D(1,2,1), new C3D(1,1,1), new C3D(2,2,1), new C3D(2,1,1), new C3D(1.5,1.5,3))
}
>> error: class Pyramid needs to be abstract, since method getCoords in class Shape of type [C <: CoordSystem]List[C] is not defined
我在this answer上看到了一些不同的想法,但它们似乎都不适合这种情况 - 因为它们似乎不允许我在其他地方编写引用myShape.getCoords
的代码好像它已在Shape
子类中正确定义,从CoordSystem
的子类返回一个对象列表。
我还在Scala Lang电子邮件列表中找到了an interesting discussion about generics,但无法将其与我的情况联系起来。
感谢任何帮助!
答案 0 :(得分:9)
这样的事情怎么样:
class CoordSystem
class C3D(val x: Double, y: Double, z: Double) extends CoordSystem
class C2D(val x: Double, y: Double) extends CoordSystem
trait ShapeLike[+C <: CoordSystem] {
def getCoords: List[C]
}
abstract class Shape extends ShapeLike[CoordSystem]
class Pyramid extends Shape with ShapeLike[C3D] {
def getCoords: List[C3D] =
List(new C3D(1, 2, 1), new C3D(1, 1, 1), new C3D(2, 2, 1), new C3D(2, 1, 1), new C3D(1.5, 1.5, 3))
}
当然,没有什么可以强迫你声明额外的类型ShapeLike
来做到这一点;其目的是允许您使用类型Shape
而不会烦恼额外的类型参数。
因此,实际上标题中所述问题的答案是:如果在超类中将其定义为协变类型参数,则可以“收紧”子类中类型参数的类型边界;相反,您可以“松开”逆变型参数的类型界限。
答案 1 :(得分:2)
类型参数是一个类型参数,超类合同要求你不要收紧合同 - 不要违反合同,不要违反合同,尽管我不认为这是合法的。
你可以做其他事情:把类型放在类中。
class Shape
class CoordSystem
class C3D(val x: Double, y: Double, z: Double) extends CoordSystem
class C2D(val x: Double, y: Double) extends CoordSystem
abstract class Shape {
type C <: CoordSystem
def getCoords: List[C]
}
class Pyramid extends Shape {
override type C = C3D
def getCoords: List[C3D] =
List(new C3D(1,2,1), new C3D(1,1,1), new C3D(2,2,1), new C3D(2,1,1), new C3D(1.5,1.5,3))
}