java - ListBuffer[BaseType] 中的协方差/子类型

标签 java scala

我有三个类,它们都实现了类似的功能,但在细微的细节上有所不同。我想创建一个抽象基类并将共享的代码移动起来。现在我卡住了。

每个子类都有一个 ListBuffer 保存另一个关系的对象,这是一些基本类型的子类。更具体地说:

trait data {
  def parseXML();
}

trait ConcreteDataA extends Data {
  override def parseXML(): Unit = {...}
}

abstract class Worker {
   protected var data: ListBuffer[Data] = _

   def loadXML(): Unit = {
     val path: String = getPath()
     ... // Parse XML-file at path and put data into data-ListBuffer 
   }

   def getPath(): String;
}

object ConcreteWorkerA extends Worker {
  data = new ListBuffer[ConcreteDataA] // Here the expected type differs

  override def getPath(): String = {
    return "pathTo/ConcreteWorkerA/s/WorkingPlace"
  }
}

我不确定如何最好地解决这个问题,感谢任何意见

最佳答案

您可以为通用参数使用通配符类型:ListBuffer[_ <: Data] .您还可以使用参数 T <: Data 使整个类/特征通用, 然后将变量声明为 ListBuffer[T] .

您还应该考虑为什么要在这里使用抽象类。你可以阅读here关于抽象类相对于特征的(很少)优势。您可能还会重新考虑为什么 data被声明为 var ,以及为什么它在 Worker 中被实例化.您可以像这样重构您的类型:

trait Worker[T <: Data]
{
   protected val data: ListBuffer[T] //Not var, and uninstantiated
   def loadXML: Unit = ???
   def getPath: String
}

object ConcreteWorkerA extends Worker[ConcreteDataA]
{
  override val data = new ListBuffer[ConcreteDataA] // Here the expected type differs
  override def getPath: String = "foo"
}

关于java - ListBuffer[BaseType] 中的协方差/子类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31439104/

相关文章:

java - 使用Spark API如何处理大型目录树?

scala - SBT 创建两个目标文件夹。这是正常的吗?

Scala逐行调度流响应

Java 和 Scala Tuple2 访问错误

java - 获取具有多个点的路线

java - 哈希码实现

java - 如何将 Scala 的 List[Double] 转换为 java.util.List[java.lang.Double]?

scala - 给定序列中的一个元素,如何获取前一个元素?

java - 3D 数组(一维平面)索引

java - 实际例子使用Hibernate FlushMode.ALWAYS