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视为不带参数的方法,并在第一次调用它们时缓存它们的输出.你没有在这里调用那个方法,你只是定义了它. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |