覆盖继承的构造函数字段时有什么区别? [英] Differences when overriding inherited constructor fields?

查看:158
本文介绍了覆盖继承的构造函数字段时有什么区别?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑这个简单的Scala类:

  A类(val d:Int)





<$ p在Scala中是否有差异(在行为或生成的字节码中) $ p> class B(d:Int)extends A(d)

  class B(override val d:Int)extends A(d)

或两者是否相同?



如果 A 会有所不同,如果它们不同,定义为 class A(var d:Int)

解决方案

对于vals,没有语义差异。但是,生成的字节码可能有差异。特别地,如果在派生类中定义的方法引用 d ,它引用构造函数参数 d ,而不是到相同名称的 val



对于vars, 行为的差异强>。如果没有重载,引用类中引用 d 的任何方法都将引用构造函数参数,而引用 d 从外面的类就会得到字段。在这种情况下,两个值可能不同(如果值自从构建以来已更改)。



这是一个演示var的行为的会话:

  scala> class A(var d:Int)
定义类A

scala> class B(d:Int)extends A(d){override def toString =d:+ d}
定义类B

scala> val b = new B(1)
b:B = d:1

scala> b.d = 2

scala> b.d
res1:Int = 2

scala> b
res2:B = d:1

此问题相关: Idiomatic Sc​​ala方式处理基础vs派生类字段名称?


Consider this simple Scala class:

class A(val d: Int)

Is there a difference in Scala (either in behaviour or generated bytecode) between

class B(d: Int) extends A(d)

and

class B(override val d: Int) extends A(d)

or are both equivalent? If they are different, what would be the specific usecase for each of them?

Would it be different if A was defined as class A(var d: Int)?

解决方案

For vals, there is no semantic difference. However, there may be a difference in the generated bytecode. In particular, if a method defined in the derived class refers to d, it refers to the constructor parameter d rather than to the val of the same name. This is implemented via an additional private field generated for the derived class.

For vars, there is a difference in behavior. Without an override, any methods that refer to d from within the derived class will be referring to the constructor parameter, while callers referencing d from outside the class will get the field. In this case, the two values may differ (if the value has changed since construction).

Here's a session that demonstrates the behavior with a var:

scala> class A(var d: Int)
defined class A

scala> class B(d: Int) extends A(d) { override def toString = "d: " + d }
defined class B

scala> val b = new B(1)
b: B = d: 1

scala> b.d = 2

scala> b.d
res1: Int = 2

scala> b
res2: B = d: 1

This question is related: Idiomatic Scala way to deal with base vs derived class field names?.

这篇关于覆盖继承的构造函数字段时有什么区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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