2012-10-02 113 views
2

标记为家庭作业。 在尝试实现一个类时,我在面向对象的世界中遇到了麻烦。斯卡拉类继承

我正在实施各种功能来对列表执行操作,我用它来模拟一组。 例如,我并不太担心自己关于如何找到工会的逻辑,但实际上只是结构。

对于如:

abstract class parentSet[T] protected() { 

    def union(other:parentSet[T]):parentSet[T] 

} 

现在我想要一个新的类扩展parentSet:

class childSet[T] private (l: List[T]) extends parentSet[T] { 
    def this() = this(List()) 
    private val elems = l 
    val toList = List[T] => new List(l) 

    def union(other:parentSet[T]):childSet[T] = { 
     for (i <- this.toList) { 
      if (other contains i) {} 
      else {l :: i} 
     } 
     return l 
    } 
} 

编译后,我收到错误,为使得类型childSet未在DEF工会发现,也不是键入T以保持参数。另外,我认为我的toList不正确,因为它抱怨它不是该对象的成员;仅举几例。

我的语法在哪里我错了?

编辑

现在我已经得到了想通了:

def U(other:parentSet[T]):childSet[T] = { 
    var w = other.toList 
    for (i <- this.toList) { 
     if (!(other contains i)) {w = i::w} 
    } 
    return new childSet(w) 

}

现在,我试图地图做同样的操作,这是什么我正在处理/使用:

def U(other:parentSet[T]):MapSet[T] = { 
    var a = Map[T,Unit] 
    for (i <- this.toList) { 
     if (!(other contains i)) {a = a + (i->())} 
    } 
    return new MapSet(elems + (a->())) 
    } 

我还想使用toL IST使它容易穿越,但我仍然得到错误类型,而与地图搞乱..

回答

2

这段代码有几个问题:

看来你没有意识到List[T]不变类型,意思是一旦创建就不能改变它的值。因此,如果您有List[T],并且您调用::方法预先设置一个值,则该函数将返回一个新列表并保留现有列表中的一个。斯卡拉有可变的集合,如ListBuffer这可能会更像你期望的行为。所以当你return l,你实际上返回原来的列表。

另外,您在使用::时订购错误。它应该去i :: l,因为::是一个右键功能(因为它以:结尾)。

最后,在你的联合方法中,你正在做(other contains i)。也许这只是Scala语法让你感到困惑,但这与做(other.contains(i))相同,并且明确contains不是parentSet的定义方法。它是List[T]类型中的一种方法,但您不要在列表中调用contains

您标记此功课,所以我不会解决你的代码,但我认为你应该

  1. 看,涉及名单的正确Scala代码一些例子,尝试here对于初学者

  2. 在Scala REPL中玩耍并尝试创建并使用一些列表,以便了解不可变集合如何工作。

+0

见上面编辑过的文章 –

1

要回答你的直接问题,即使childSet继承parentSet,原始方法指定parentSet作为返回类型而不是childSet。你可以只使用parentSet作为类型OR,你可以指定返回类型是继承parentSet的任何东西。