加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

scala – 覆盖val的行为的基本原理

发布时间:2020-12-16 19:10:41 所属栏目:安全 来源:网络整理
导读:class A { val x = println("A") }class B extends A { override val x = println("B")}(new B).x 打印: AB 然而, class A { lazy val x = println("A") }class B extends A { override lazy val x = println("B")}(new B).x 打印只是: B According to Mar
class A { 
  val x = println("A") 
}
class B extends A {
  override val x = println("B")
}
(new B).x

打印:

A
B

然而,

class A { 
  lazy val x = println("A") 
}
class B extends A {
  override lazy val x = println("B")
}
(new B).x

打印只是:

B

According to Martin Odersky,至少在非惰性情况下,行为是“如指定的”.我很好奇为什么行为是这样指定的,以及为什么它在val是懒惰的时候会有所不同.

解决方法

在成员定义之外的类定义的模板(“body”)中的代码是构造函数中的代码.初始化子类的实例时总是调用父类的构造函数(在这种情况下,您调用的是没有参数的构造函数,否则语法将是B类扩展A(arg1,arg2){…}) .有关更多详细信息,请参见 Scala Language Specification中的第5.1节.

这就是为什么在第一种情况下评估println(“A”)的原因; val定义是构造函数代码的一部分.

当您考虑第二个示例中构造时发生的情况时,您从未询问过A中定义的x值;因为它是一个懒惰的val,所以在需要它之前不会计算它.

您可以将lazy val视为不带参数的方法,并在第一次调用它们时缓存它们的输出.你没有在这里调用那个方法,你只是定义了它.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读