2015-01-06 33 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) 

}