Родительские поля и родительский конструктор всегда инициализируются и запускаются перед дочерним полем и конструктором.Это означает, что вызов a
происходит до того, как ваш var s
установлен в дочернем классе.
В общем, плохая идея вызывать виртуальный метод из конструктора;C ++ даже запрещает его (или, вместо того, чтобы запрещать его, не вызывает метод, реализованный в дочернем классе при вызове из конструктора суперкласса).
Однако вы можете это исправить, если включите var s
вместо class Y
в lazy val
или def
.lazy val
s инициализируются при первом обращении к их значению, независимо от того, кем;def
s не создает проблем с инициализацией, таких как var
s или val
s.Однако будьте осторожны, чтобы не вызывать любую другую неинициализированную структуру из реализации a
, так как та же проблема появится снова.
Редактировать:
Вытакже можно использовать функцию «ранних определений» (или ранней инициализации) в Scala:
class Y extends {
var s = "Hello"
} with X {
def a: Unit = println ("String is "+s)
}