Add an example using pre-initialized fields in synthetic objects for working with traits.
Add an example using pre-initialized fields in class definitions for working with traits.
Add an example of using lazy vals for working with traits.

In this new trait definition, all concrete fields are defined lazy.
Another change with respect to the previous definition of RationalTrait,
is that the require clause was moved from the body of the trait to
the initializer of the private field, g, which computes the greatest
common divisor of numerArg and denomArg. With these changes, there’s
nothing that remains to be done when LazyRationalTrait is initialized;
all initialization code is now part of the right-hand side of a lazy val.
Therefore, it is safe to initialize the abstract fields of LazyRationalTrait
after the class is defined.

Note that the definition of g comes textually after the definitions of
numerator and denominator in class LazyRationalTrait. Nevertheless,
because all three values are lazy, g gets initialized before the
initialization of numerator and denominator is completed. This shows
an important property of lazy vals: the textual order of their definitions
does not matter, because values get initialized on demand. Therefore,
lazy vals can free you as a programmer from having to think hard how
to arrange val definitions to ensure that everything is defined
when it is needed.

However, this advantage holds only as long as the initialization of lazy
vals neither produces side effects nor depends on them. In the presence
of side effects, initialization order starts to matter. And then it can
be quite difficult to trace in what order initialization code is run.
So lazy vals are an ideal complement to functional objects, where
the order of initializations does not matter, as long as everything
gets initialized eventually. They are less well suited for code
that’s predominantly imperative.