请看一下下面的代码,其中Extractor[A,B]
是通用框架的一部分,其他所有内容都应该被视为“客户端代码”(我对它进行了相当多的简化并重命名了所有内容。所以不要介意Extractor
好像不太有用)。
scala> abstract class Extractor[A,B] {
| def extract(d:A):B
| def stringRepr(d:A):String
| }
defined class Extractor
scala> sealed abstract class Value
defined class Value
scala> case class IntValue(i:Int) extends Value
defined class IntValue
scala> case class StringValue(s:String) extends Value
defined class StringValue
scala> case class Data(i:Int, s:String)
defined class Data
scala> sealed abstract class MyExtractor[Value] extends Extractor[Data, Value] {
| def stringRepr(d:Data) = extract(d) match {
| case IntValue(i) => i.toString
| case StringValue(s) => s
| }
| }
defined class MyExtractor
scala> class IntExtractor(name:String) extends MyExtractor[IntValue] {
| def extract(d:Data) = IntValue(d.i)
| }
defined class IntExtractor
scala> class StringExtractor(name:String) extends MyExtractor[StringValue] {
| def extract(d:Data) = StringValue(d.s)
| }
defined class StringExtractor
简而言之Extractor[A,B]
用于提取一些价值B
from A
并执行此显示代码中未表示的其他一些操作。抽象类Value
and MyExtractor
出于“客户端代码”中类型安全的原因而使用。
当我尝试创建一个List
of MyExtractor
即,会发生以下情况:
scala> val l = List.empty[MyExtractor[Value]]
l: List[MyExtractor[Value]] = List()
scala> new IntExtractor("test1") :: l
res5: List[MyExtractor[_ >: IntValue <: Value]] = List(IntExtractor@1fd96c5)
试图转换一个IntExractor
到超类
scala> new IntExtractor("test"):MyExtractor[Value]
<console>:24: error: type mismatch;
found : IntExtractor
required: MyExtractor[Value]
new IntExtractor("test"):MyExtractor[Value]
^
scala> new IntExtractor("test"):Extractor[Data,Value]
<console>:24: error: type mismatch;
found : IntExtractor
required: Extractor[Data,Value]
new IntExtractor("test"):Extractor[Data,Value]
当我定义时,我知道一切都很好IntExtractor
像这样
scala> class IntExtractor(name:String) extends MyExtractor[Value] {
| def extract(d:Data) = IntValue(d.i)
| }
defined class IntExtractor
scala> new IntExtractor("test"):Extractor[Data,Value]
res17: Extractor[Data,Value] = IntExtractor@1653d7a
但我不明白,为什么它按照我上面尝试的方式不起作用。
我将不胜感激任何帮助或提示。