Scala中的继承和初始化

Bil*_*ill 2 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("//")

  // ....
}
Run Code Online (Sandbox Code Playgroud)

问题是,lineFilternullparseData,大概是因为parseData是当主称为GenericParser构造仍在运行,所以子类还没有完全初始化它的成员.

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

Jea*_*let 6

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

Scala 2.8:如何初始化子类

你基本上可以复制粘贴问题的答案形式.方案包括:

  • def或者lazy 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("//")
    }
    
    Run Code Online (Sandbox Code Playgroud)