Scala 2.8:如何初始化子类 [英] Scala 2.8: how to initialize child class

查看:41
本文介绍了Scala 2.8:如何初始化子类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑以下代码:

abstract class X {
  def a:Unit
  a
}

class Y extends X {
  var s:String = "Hello"
  def a:Unit = println ("String is "+s)
}

这给出了以下输出:

scala> new Y
String is null
res6: Y = Y@18aeabe

如何让父类X在调用a

推荐答案

父字段和父构造函数总是在子字段和构造函数之前初始化和运行.这意味着对 a 的调用发生在您的 var s 在子类中设置之前.

The parent's fields and the parent constructor are always initialized and run before the children's field and constructor. It means that the call to a happens before your var s is set in the child class.

一般来说,从构造函数调用虚方法是个坏主意;C++ 甚至不允许它(或者,而不是不允许它,当从超类的构造函数调用时,不调用子类中实现的方法).

In general, it's a bad idea to call a virtual method from a constructor; C++ even disallows it (or, rather than disallowing it, doesn't call the method implemented in the child class when called from the superclass's constructor).

但是,如果将 class Y 中的 var s 转换为 lazy valdef<,则可以修复它/code> 代替.lazy vals 在第一次访问它们的值时被初始化,无论是谁;defs 没有像 vars 或 vals 这样的初始化问题.但是,请注意不要从 a 的实现中调用任何其他未初始化的结构,因为同样的问题会再次出现.

However, you can fix it if you turn your var s in class Y into a lazy val or a def instead. lazy vals are initialized the first time their value is accessed, no matter by whom; defs pose no initialization issues like vars or vals. However, be careful not to call any other uninitialized structure from within the implementation of a, as the same problem will show up again.

您还可以使用 Scala 的早期定义"(或早期初始化)功能:

You can also use Scala's "early definitions" (or early initialization) feature:

class Y extends {
  var s = "Hello"
} with X {
  def a: Unit = println ("String is "+s)
}

这篇关于Scala 2.8:如何初始化子类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆