Welcome to WuJiGu Developer Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
434 views
in Technique[技术] by (71.8m points)

dart - Difference between assigning the values in parameter list and initializer list

class A {
  A(int value);
}

class B extends A{
  final int foo;

  B.one(this.foo) : super(foo); // Works

  B.two(int foo) : foo = foo, super(this.foo); // Doesn't work
}

In B.one, I can easily pass the value of foo to super but in B.two, I can't do that. In both cases, the field foo is assigned before calling super, in one case it works and in another it fails. So, the question is at what point the fields are created in the constructor.

Question&Answers:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Dart constructs objects in two phases: first outside-in and then inside-out.

Initializer lists are executed outside-in (from derived class to base class). After this is done, the object's members should be initialized, the object is considered to be "constructed", and this exists. (That's why you can't use this in a meaningful way in an initializer list; it doesn't exist yet.) (Technically direct member initialization occurs before initializer lists, but I'm lumping them together for simplicity.)

Constructor bodies are then executed inside-out (from base class to derived class).

This approach guarantees that the object's members are initialized when the base class constructor body executes, allowing virtual dispatch to occur in the constructor. (In contrast, C++ constructs objects purely inside-out and disallows virtual dispatch in constructors and destructors. Or contrast to Java where, IIRC, the class mostly defines its own construction order, and the classes are responsible to ensure that any virtual function calls performed by the constructor are safe.)

Without this approach, a Dart constructor body either cannot guarantee safety when executing virtual functions (the Java approach) or must disallow virtual dispatch (the C++ approach).

One consequence of this approach is that final variables can be initialized by initializer lists but not by constructor bodies: when the constructor body executes, all member variables (that aren't late and that aren't nullable) are expected to be initialized already.

Also see:


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to WuJiGu Developer Q&A Community for programmer and developer-Open, Learning and Share
...