2012-10-02 153 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的任何東西。