Scala中的继承和初始化

时间:2011-04-30 13:45:50

标签: scala

我有两个看起来像这样的Scala类(释义):

abstract class GenericParser[T] {
  val lineFilter : String => Boolean

  parseData()

  def parseData() : T {
    for( line <- .... if lineFilter(line) )
      // do things
  }
}

class SalesParser extends GenericParser[SalesRow] {
  val lineFilter = line => !line.startsWith("//")

  // ....
}

问题是lineFilternullparseData,大概是因为parseData在主要GenericParser构造函数仍在运行时被调用,所以子类尚未完全初始化其成员。

我可以通过将lineFilter设为def而不是val来解决这个问题,但这是预期的行为吗?在运行时获得NPE之后,这个问题才会变得明显,这似乎是不对的。

1 个答案:

答案 0 :(得分:6)

这确实是预期的行为,与此问题完全相同:

Scala 2.8: how to initialize child class

您基本上可以复制粘贴该问题的答案表单。解决方案包括:

  • deflazy val代替val
  • 早期初始化lineFilter
  • 重新设计类以避免“从超类的构造函数中访问未初始化的子类值的虚拟方法调用”问题。例如,为什么要将过滤函数存储在val中或从def返回,而它可以作为方法实现?

    abstract class GenericParser[T] {
      def lineFilter(line: String): Boolean
    
      parseData()
    
      def parseData() : T {
        for( line <- .... if lineFilter(line) )
          // do things
      }
    }
    
    class SalesParser extends GenericParser[SalesRow] {
      def lineFilter(line: String) = !line.startsWith("//")
    }