Consider the code below
class Meal {
Meal() { System.out.println(\"Meal()\"); }
}
class Bread {
Bread() { System.out.println(\"Bread()\"); }
I think there are two things going on here that are throwing you off. The first is that main is a static method, where as the member variables b, c, and l are non-static instance variables. That means that they belong to the objects of the class, not the class itself. So when the class is initialized to run the main method, the contructors of Bread, Cheese, and Lettuce are not called, since no instances of Sandwich have been created.
Not until main actually run, and calls new Sandwich() are any objects actually constructed. At that point, the order of operations is:
- initialize member fields of the base class(es)
- run the base class(es) constructor(s)
- initialize member fields of this class
- run the constructor of this class
This is done recursively, so in this case, the order would be
- init fields of Meal (none)
- run constructor of Meal (prints "Meal")
- init fields of Lunch (none)
- run constructor of Lunch (prints "Lunch")
- init fields of PortableLunch (none)
- run constructor of PortableLunch (prints "PortableLunch")
- init fields of Sandwich (prints "Bread", "Cheese", and "Lettuce")
- run constructor of Sandwich (prints "Sandwich")
The purpose of this order is to ensure that the base class is fully initialized before any code in the subclass is run. This is needed because the within the constructor of the sub-class, it may call a method on the base class. Bad things would happen if that base class did not initialize its members first.