尝试以下操作:
包inputabstraction
abstract class Point[T](n:String){
def value: T
val name = n
}
case class Input[T](n:String, value:T) extends Point[T](n)
object testTypedCaseClass{
def test(){
val foo = Input("foo", "bar")
println(foo)
}
}
一个简单的应用,以检查它的工作原理:
import inputabstraction._
object TestApp extends Application{
testTypedCaseClass.test()
}
说明
您所做的第一个错误是case class Input[Type](n:String) extends Point(n){
。 Point是一个类型化的类,因此当您使用extends Point(n)
调用超类的构造函数时,您需要指定Point
的类型。这是这样完成的:extends Point[T](n)
,其中T是您计划使用的类型。
第二个错误是您既定义和声明值:T在这里:var value: Type = _
。在这个声明中,_
是一个值。它的值是Nothing
。 scala编译器从此推断出Point[T]
是Point[Nothing]
。因此,当您尝试将其设置为setValue
方法正文中的类型时,必须将其设置为Nothing
,这可能不是您想要的。如果您尝试将其设置为除Nothing
之外的任何内容,则会从上面得到类型不匹配,因为由于您使用了_
,所以键入的值为Nothing
。
第三个错误是使用var
而不是val
或def
。val
和def
可以互换覆盖,这意味着亚型可与val
或def
覆盖,和Scala编译器会看着办吧你。它是用来定义瓦尔斯如使用抽象类和特质def
功能的最佳做法,因为亚型构造函数初始化顺序是一件很困难的事情得到正确的(没有为编译器如何确定如何从它的超类型构造一个类的algorithm )。 TL#DR ===在超类型中使用def。大小写类参数会自动生成val
字段,由于您要扩展Point,因此将创建val值字段,该字段将覆盖Point[T]
中的def值字段。
你可以摆脱这一切Type
||因为类型推断和Point
是抽象的事实,因此可以通过val扩展值。
做的依赖注入这样的首选方式是cake pattern,但这个例子我已经提供了您的用例的作品。
这个答案不正确。仅仅添加类型的情况下类,当他试图用'setValue'与除'Nothing'任何其它类型不会编译: '抽象类Point [T](n为字符串){ VAR值:T = _ VAL名称=正 } 情况下类输入[T](n为字符串)延伸点[T](N){ DEF的setValue(VA:T)=值= VA } 对象testTypedCaseClass { DEF测试(){ VAL富=输入( “foo” 的) foo.setValue( “条”) 的println(富) } }' RESU lts在: 'type mismatch;' 编译时 这是因为他在'Point [T]'中声明的值是'Nothing'。 – 2012-04-23 21:02:37
不能相信我犯了这个简单的错误。事实上,这是错误的一部分,但如果我改变了这一点,并保留其余部分,它给了我同样的错误。 – 2012-04-23 21:10:59
作为@JackViers提到的,使用默认值,再加上一些通用的类型为价值是相当混乱,这将实现默认值加上一个setter这是不是在同一层上,但我不把所有的代码,所以我建议一个简单的“补丁”。请毫不犹豫地在您的问题中提供更多细节。 – 2012-04-23 21:14:00