2014-01-14 52 views
1
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())) 
    } 
    } 
} 

回答

2

在任何类型定义(类或性状)的类型可作为this.type,但是这是一个相关的路径类型和类型的每个实例具有不同的this.type。的this.type最常见的用途是通知的是,方法返回上它被调用同一实例客户端代码。

0

您正在寻找不直接在Scala中建模的MyType概念。编码是最常用的方法是用F-bounded polymorphism,这是在Java中枚举下盖也采用:

public abstract class Enum<E extends Enum<E>> { 
    public final int compareTo(E o) { ... } 
    public final Class<E> getDeclaringClass() { ... } 
} 

在Scala中,你也可以用有限的抽象类型成员,马丁在联线中指出:

abstract class C { 
    type MyType <: C 

    def foo: MyType 
} 

case class D(x: Int) extends C { 
    type MyType = D 

    def foo = D(123) 
} 
相关问题