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'不能從那個實例讀取。 –