Home > Net >  How is abstract method initialiazed in Scala 3?
How is abstract method initialiazed in Scala 3?

Time:01-18

The following Scala 3 code

trait MyTrait:
  println("MyTrait initialization – start")
  val value: Int
  def data: String
  println(s"MyTrait initialized end with value=$value, data=$data")

@main
def main(): Unit = {
  new MyTrait: // anonymous subclass
    println("Anonymous subclass initialization – start")
    val value = 1
    def data =
      println("Calling data inside anonymous subclass")
      "abc"
    println("Anonymous subclass initialization – end")
}

prints

MyTrait initialization – start
Calling data inside anonymous subclass
MyTrait initialized end with value=0, data=abc
Anonymous subclass initialization – start
Anonymous subclass initialization – end

I don't understand why it prints data=abc. Shouldn't it print some default value or compilation error eccur?


The initialization order is MyTrait followed by the anonymous subclass. In MyTrait, abstract members should have been set to their default value – this holds for value, as it prints 0. However, for a method data, it somehow skips this initialization order and calls the concrete data method from the anonymous subclass before its initialization should happen.

CodePudding user response:

vals and vars (or technically the fields backing them) are initialized with default values. defs (aka methods) are effectively bound at compile time and virtual method dispatch means that the methods may be called before the constructor for the class has completed.

The effective flow is:

  • allocate memory for the anonymous subclass (at this point def data is bound to the anonymous subclass's implementation and fields have their default values)
  • call the anonymous subclass's constructor
  • ...which calls the trait's constructor
  • then runs the rest of the body of the subclass's constructor
  • Related