Инициализация объекта Dart определена так, чтобы работать так, как вы наблюдаете.
Когда вы пишете new Foo(...)
, язык выделяет пространство для объекта Foo
, а затем проходит процесс инициализации для Foo
class и все его суперклассы.
Инициализация экземпляра Foo
происходит следующим образом:
- Сначала оцените инициализаторы поля экземпляра, объявленные в
Foo
в порядке исходного кода. - Затем оцените список инициализаторов класса
Foo
. - Затем рекурсивно инициализируйте экземпляр как суперкласс
Foo
, как указано при вызове super
списка инициализаторов (по умолчанию super()
, если вы ничего не пишете). - Когда закончите с этим, выполните тело конструктора
Foo
.
Когда этот процесс достигнет класса Object
, объект считается правильно инициализированным и доступным для тел конструктора, которые выполняются на обратном пути.
Например:
Object log(Object value) {
print(value);
return value;
}
class Super /* extends Object */ {
var superField6 = log(6);
var superField9;
Super(this.superField5) : superField8 = log(8), superField9 = log(9) {
log(10);
}
var superField7 = log(7);
var superField8;
var superField5;
}
class Sub extends Super {
var subField1 = log(1);
var subField4;
Sub() : subField3 = log(3), subField4 = log(4), super(log(5)) {
log(11);
}
var subField2 = log(2);
var subField3;
}
main() {
new Sub();
}
Если вы запустите t его код, вы увидите log
звонки, происходящие в порядке их аргументов.