2015-01-06 56 views
1

我已經開始在scala上工作了。到了我想正確使用繼承的地步。斯卡拉小孩listbuffer返回作爲父列表緩衝區

我被困在一次地方。我試圖在線閱讀文檔和其他信息。但我似乎被卡住了。 請看看這個,告訴我你是否曾經遇到過這種情況,以及我是否在做一些真正錯誤的事情。

所以,這是我的方法:

def getFacethierarchy): ListBuffer[BaseClass] = { 
     val obj: Childclass = new ChildClass(1, "2") 
     val list: ListBuffer[ChildClass] = ListBuffer[ChildClass]() 
     list += obj 
     list 
    } 


class BaseClass(var id: Int){ 
} 

class ChildClass(id: Int, var name: String) extends BaseClass(id){ 
} 

現在Scala是不是讓我回到一個ChildClass實例。 在Java中,這將工作(孩子是父類型)

我試圖改變我的方法簽名返回「任何」。 我不知道我出錯了。 請儘可能幫忙。

更新: 爲了更具體地瞭解我在做什麼,我更新了代碼段。

+0

什麼是編譯器在說什麼? –

+0

由於代碼中存在語法錯誤,並且在未給定定義的情況下引用變量,所以您真的不清楚要實現的內容。 – Ryan

+0

BaseClass類型的表達式無法轉換爲ChlidClass – Roger

回答

0

該問題源於事實ListBuffer是不變的,而不是協變(+之前T)。它不可能是協變的。由於這個原因,即使ChildClassBaseClass的子類型,ListBuffer[ChildClass]也不是ListBuffer[BaseClass]的子類型。

您可以使用存在類型(: ListBuffer[T] forSome {type T <: BaseClass}(希望我使用了正確的語法)),或爲要使用的方法提供附加類型參數(yourMethod[T <: BaseClass]: ListBuffer[T])。如果你想「MyTypes」(可能是,很難說沒有進一步的細節):Scala do not support it.

以你的代碼仔細看看,你可能更願意返回List[BaseClass]代替,這是協變的,所以你可以寫:

def getFacethierarchy: List[BaseClass] = { 
     val obj: Chlidclass = new ChildClass(1, "2") 
     val list: ListBuffer[ChildClass] = ListBuffer[ChildClass]() 
     list += obj 
     list.toList 
} 
1

ListBuffer[ChildClass]不是ListBuffer[BaseClass]因爲ListBuffer是一個可變的數據結構,它會破壞類型安全的子類型。

你要避免類似:

val l : ListBuffer[Int] = ListBuffer[Int](1, 2, 3) 
val l2 :ListBuffer[Any] = l 
l2(0) = 2.54 

你可以做的是簡單地創建一個ListBuffer[BaseClass]

def getFacethierarchy): ListBuffer[BaseClass] = { 
    val obj: Chlidclass = new ChildClass(1, "2") 
    ListBuffer[BaseClass](obj) 

}