当您覆盖方法时,Scala 类 中的指令顺序如何工作

How does the order of instructions works inside Scala classes when you override a method

我正在第一次体验 Scala,尝试基本概念。我做了一个非常简单的 class,通过覆盖 toString 进行恶作剧,以便在创建时打印 class 实例:

class Person(var firstName: String, var lastName: String) {
  println(this)
  override def toString: String = "Overriden toString"
  println(this)
}
val p = new Person("John", "Smith")

我想知道如果我 运行 这段代码会发生什么。在覆盖 toString 之前的第一个 println 应该是

PlatformName$Person@address

如果我理解正确的话,这就是在不覆盖 toString 的情况下打印 class 实例时应该得到的结果。但是相反,两幅建筑印刷品都印刷了

Overriden toString.

为什么会这样? override 是否优先于任何其他代码,忽略顺序,或者它是如何工作的?

有2种观点(个人认为): 第一个是 toString 方法是在编译时评估的,但是 println 是在创建对象并在运行时完成的。 第二是当你想打印一些东西时,你隐式地调用了 .toString() 方法(不仅在 Scala 中,在 Java 和 ... 中也是如此),所以需要首先评估该方法,然后你调用它(隐含地)你碰巧看到覆盖字符串每当你打印那个对象时。

当你定义这样一个 class 时,你基本上是在写同样的东西:

class Person {

  var firstName: String
  var lastName: String

  // Constructor
  def this(firstName: String, lastName: String) = {
    // Regular constructor member definition
    this.firstName = firstName
    this.lastName = lastName
    // The code you wrote in the class body
    println(this)
    println(this)
  }
  
  override def toString: String = "Overriden toString"
}

在 class 中编写的不属于 def 的代码将在创建 class 的实例时执行(在 构造函数中 在 运行 时间)。

class 的 def 都是在你实例化 class 之前定义的(在编译时),无论是顺序还是 override