abstract class BaseSourceReader[T <: BaseSource] {
/**
* Method to read data from source
*/
def readFromSource(identifier: T): Seq[String]
}
// Trait common to all source identifiers
trait BaseSource
派生类
class XYZSourceReader(param1: String) extends BaseSourceReader[XYZBaseSource] {
override def readFromSource(identifier: XYZBaseSource): Seq[String] =
// some implementation
}
case class XYZBaseSource(
paramA: String,
paramB: Seq[String]) extends BaseSource
现在我想要做的就是注入基础源阅读器的通用类,以便实现独立来源的:
class MySourceTrasformerJob(
val sourceReader: BaseSourceReader[BaseSource]) {
// some code
}
并且像这样使用它:
class MyTransformerJobApp {
val reader = new XYZSourceReader(param)
val job = MySourceTrasformerJob(reader)
}
对于此代码段工作时,编译器提示class SourceReader is invariant in type T. You may wish to define T as +T instead. (SLS 4.5)
我试图更新BaseSourceReader
:
- abstract class BaseSourceReader[T <: BaseSource] { + abstract class BaseSourceReader[+T <: BaseSource] {
但这导致与readFromSource
方法错误的错误:协变型T在价值标识符的类型T中发生在逆变位置。
一个可行的解决方案,我发现被捆绑实施的源代码,但它不是“通用”,足以实现:
class MySourceTrasformerJob(
val sourceReader: BaseSourceReader[XYZBaseSource]) {
// some code
}
我有点陷在这个循环和尝试模型更新,任何建议的方式来处理这个,但绝对坚持通用抽象类依赖注入?
看看为什么这是必须的:考虑如果一个'BaseSource'的实例而不是'XYZBaseSource'的实例被传入'MySourceTrasformerJob'的'sourceReader'的'readFromSource'方法会发生什么。你的原始类型表明应该是可能的,但是'XYZSourceReader'不能从那个实例读取。 –