Consider the code below
class Meal { Meal() { System.out.println("Meal()"); } } class Bread { Bread() { System.out.println("Bread()"); } } class Cheese { Cheese() { System.out.println("Cheese()"); } } class Lettuce { Lettuce() { System.out.println("Lettuce()"); } } class Lunch extends Meal { Lunch() { System.out.println("Lunch()"); } } class PortableLunch extends Lunch { PortableLunch() { System.out.println("PortableLunch()");} } class Sandwich extends PortableLunch { private Bread b = new Bread(); private Cheese c = new Cheese(); private Lettuce l = new Lettuce(); public Sandwich() { System.out.println("Sandwich()"); } public static void main(String[] args) { new Sandwich(); } }
Based on my understanding of class member initialization and order of constructor execution. I expected the output to be
Bread() Cheese() Lettuce() Meal() Lunch() PortableLunch() Sandwich()
as i believe the class members were initialized even before the main method was called. However I had the below output when i ran the program
Meal() Lunch() PortableLunch() Bread() Cheese() Lettuce() Sandwich()
my confusion is whey the Meal() Lunch() and PortableLunch() run before Bread() Cheese() and Lettuce() even though their constructors where called after.
For multiple inheritance order of constructor call is, the base class's constructors are called in the order of inheritance and then the derived class's constructor.
Order of execution of constructor in Single inheritance In single level inheritance, the constructor of the base class is executed first. Output: Order of constructor execution... ParentClass constructor executed.
Yes it matters. In the example above, the first argument has to be an integer, and the second has to be a string. Constructors are chosen according to the rules in the language spec. TL;DR: yep, there have to be same number, and they've got to be in the same order.
These are instance fields
private Bread b = new Bread(); private Cheese c = new Cheese(); private Lettuce l = new Lettuce();
They only exist (execute) if an instance is created.
The first thing that runs in your program is
public static void main(String[] args) { new Sandwich(); }
Super constructors are called implicitly as the first thing in each constructor, ie. before System.out.println
class Meal { Meal() { System.out.println("Meal()"); } } class Lunch extends Meal { Lunch() { System.out.println("Lunch()"); } } class PortableLunch extends Lunch { PortableLunch() { System.out.println("PortableLunch()");} }
After the super()
calls, instance fields are instantiated again before the constructor code.
The order, reversed
new Sandwich(); // prints last // the instance fields super(); // new PortableLunch() prints third super(); // new Lunch() prints second super(); // new Meal(); prints first
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With