在scala中重写val

在scala中重写val,scala,Scala,我对以下几点感到困惑: class A(val s: String) { def supershow { println(s) } } class B(override val s: String) extends A("why don't I see this?"){ def show { println(s) } def showSuper { super.supershow } } object A extends App { val

我对以下几点感到困惑:

class A(val s: String) {
 def supershow {
   println(s)
 } 
}


class B(override val s: String) extends A("why don't I see this?"){
  def show {
    println(s)
  }
  def showSuper {
    super.supershow
  }
}

object A extends App {
  val b = new B("mystring")
  b.show
  b.showSuper
}
我期待着:

mystring
why don't I see this?
但我得到:

mystring
mystring

在java中,如果重写或“隐藏”超类中的变量,则超类有自己的变量。但是在这里,即使我认为我用不同的字符串显式初始化父类,父类也会被设置为与子类相同的值。

scala
val
中类似于
java
中的getter方法。您甚至可以使用
val
覆盖
def

如果您需要类似于
java
字段的内容,则应使用
private[this]val

class A(private[this] val s: String) {
  def superShow() = println(s)
}
class B(private[this] val s: String) extends A("why don't I see this?") {
  def show() = println(s)
}

val b = new B("message")
b.show
// message
b.superShow()
// why don't I see this?

非常感谢。这很有用,尽管我现在对val、var和override完全感到困惑。你知道他们是如何工作的吗,以及背后的理念?目前,这在我的脑海中是一个很大的混乱-看起来像是scala烹饪书中针对不同情况的许多特殊规则“如示例所示,trait的字段可以声明为var或val。您不需要使用override关键字来重写子类(或trait)中的var字段,但您确实需要使用它来覆盖val字段”。我找不到基本的一致性。谢谢@布鲁斯:我敢肯定,有这样的答案<代码>定义-方法
val
-“稳定”方法(getter),在构造函数中初始化
var varName:T
-一对方法
def varName:T
def vatName_=(T):单位
lazy val
-“稳定”方法实现为双重检查锁。您可以使用{
def
val
var
lazy val
}中的任何一种覆盖
def
,也可以使用
val
覆盖
lazy val
。谢谢。我已经阅读了很多scala书籍,还没有看到val被描述为一种方法,甚至没有被描述为一种类似的方法。然而,你描述它的方式似乎是看待事物的一种很好的方式,可能会帮助我理解它。。谢谢你的帮助@布鲁斯:看。太棒了,谢谢-我来看看。看起来是一个很好的系列文章。