abstract class TileStack {
def foo = 1 + 1
def extendRight: HashSet[_ <: TileStack]
}
class SquareTileStack extends TileStack {
def extendRight = {
def rec(currentStack: SquareTileStack = new SquareTileStack) = {
// if(currentStack.isDoneRecursing)
// else rec(currentStack)
}
rec()
}
}
class TriangleTileStack extends TileStack {
def extendRight = {
def rec(currentStack: TriangleTileStack = new TriangleTileStack) = {
// if(currentStack.isDoneRecursing)
// else rec(currentStack)
}
rec()
}
}
object Tiler {
def bar[T <: TileStack](stackList: HashSet[T]) = {
var stackDictionary: HashSet[(T, HashSet[T])] = HashSet()
for(stack: [T] <- stackList){
hashOfHash += ((stack, stack.extendRight))
}
}
}
有两个问题: 1)此代码不会因为方法Tiler.bar
的编译。这是因为stackDictionary
预计值类型HashSet[T]
其中T <: TileStack
但取而代之的是一些随机值_ <: TileStack
。实际上,T实际上是由extendRight
返回的,但这并不是在抽象类中指定的。我想要做的是这样的:如何指定的抽象方法的返回类型为实现类型
abstract class TileStack {
def foo = 1 + 1
def extendRight: HashSet[this]
}
但这显然是不允许的。解决办法是什么? 2)请注意,extendRight的实际实现是丑陋的。这是因为extendRight旨在成为递归方法,它采用当前类型的默认参数,并将其构建为this
的扩展。但是,我无法弄清楚如何在没有遇到类型问题的情况下为接口方法提供默认参数。
运用SOM-snytt的建议,这是我想出了一个解决方案。我觉得这是一个令人难以置信的奇怪的构造,以这种方式使用类型参数,但它是这样。
abstract class TileStack[Repr <: TileStack[Repr]] {
def foo = 1 + 1
def make(): TileStack[Repr]
def extendRight(currentStack: TileStack[Repr] = make): HashSet[Repr]
}
class SquareTileStack extends TileStack[SquareTileStack] {
def make = new SquareTileStack
def extendRight(currentStack: TileStack[SquareTileStack] = make) = {
new HashSet[SquareTileStack]
}
}
class TriangleTileStack extends TileStack[TriangleTileStack] {
def make = new TriangleTileStack
def extendRight(currentStack: TileStack[TriangleTileStack] = make) = {
new HashSet[TriangleTileStack]
}
}
class Tiler {
def bar[Repr <: TileStack[Repr]](stackList: HashSet[Repr]) = {
var stackDictionary: HashSet[(Repr, HashSet[Repr])] = HashSet()
for (stack <- stackList) {
stackDictionary += ((stack, stack.extendRight()))
}
}
}