When object initialization is done, all superclasses are initialized prior to the subclasses. Therefore, when the new SQ21 object is created in main, the constructor for Q21 is implicitly called first. That constructor invokes the method methodA(). This is an instance method, so dynamic-binding is used (method overriding) and the methodA() in the class SQ21 is called. That prints the value of b, but that variable hasn't been initialized yet, so it displays a value of 0. Once the superclass' initialization is complete, initialization of the sublcass, SQ21 can begin. The member b is initialzied to 126 and the constructor of SQ21 is called, which displays the value of b. I hope that helps. You can find detailed information about the initialization process in the JLS, §12.4 Initialization of Classes and Interfaces. Corey
Corey, Do I understand you correctly to be saying that when the constructor for Q21 is invoked:
the call to methodA() actually refers to the method of SQ21 rather than Q21. I'm surprised by this from an intuitive point of view; the method is called on "this," which refers to a Q21 object. So why would dynamic lookup pick out the method of SQ21 instead? Could you please explain the logic behind this conter-intuitive dynamic lookup?
Originally posted by Dave Winn: ...the method is called on "this," which refers to a Q21 object...
No it doesn't! The object is question is of type SQ21 (look at the line in the main method). You should see where it says:
Therefore, when it comes time to determine which method to invoke, the type SQ21 is used. Don't forget that, even though you're executing a method within a parent class, the actual object that the method was invoked on might be a subclass of that parent class. If you're still confused, please ask. I hope that helps, Corey
Corey, Thanks for the explanation. I'm not confused anymore, just surprised that the reference of "this" can be a little more fluid than I previously thought (at least when it is used inside constructors).
Just remember, a Q21 object is never being created. Rather, superclass state needs to be initialized prior to the subclass in order to ensure that any initialization needed in the superclass is done prior to that of the subclass. Take the following example:
As you can see, the member variable x, even though it is inherited by the subclass, is only initialized in the superclass. This can be true for lots of situations. Think about any time you extend a class - do you rewrite code to initialize all of the member that you inherited? Of course not! Therefore, the rule is that the superclass is initialized prior to the subclass to ensure that any inherited members have been properly initialized prior to the subclass using them (as in the example above). Just remember that no Q21 object was created, only a SQ21 object. Therefore, this can only reference one object, that of type SQ21. No object of type Q21 exists - we're really just initializing inherited members of SQ21 by executing initialization procedures of the parent class. I hope that helps, Corey
Hi Corey, I don't understand why "variable b hasn't been initialized yet, so it displays a value of 0." From my understanding, instance variable will be initialized first, then the constructor will be called. If this is the case, varible b should be initialized to 126 before calling SQ31 constructor. so I was expecting the output to be 3.Value of b is:126 2.Value of b is:126 but i realized i was wrong after i run the code. Please help me to understand. Thanks!
Hi Xu Zing, what i think is the first line in the output "value of b is 0", is not printed from constructor, instead from the amethod(), the second line is printed from the constructor, thats y, initially is prints b = 0, and when constructor is called(i.e b is initialized) then b = 126. flow of execution of program- 1.new subclass() 2.subclass constructor invocked 3.but before executing any code in subclass constructor, first superclass constructor is called. 4.superclass constructor is calling this.amethod() 5.since this method is overridden, then subclass amethod() is called. 6.subclass amethod() prints "value of b = 0" as expected. 7.Now when superclasss constructor is finished, code in subclass constructor is executed. 8.now "value of b = 126" is printed as b is initialized now. Hey Corey! plz comment am i right? Regards, Vinita
This is my understanding about how this works : Before a class is initialized it's direct superclass must be initialized but interfaces implemented by the class need not be initialized(JLS �12.4.1). This is what happens here when the subclass is instantiated. 1) Memmory is allocated to the field b. 2) The fields are initialized to their default values. 3)Superclass constructor is called Q21() which invokes method methodA()[ This is because superclass has to be initialized before subclass] Due to dynamic binding(overiding)i.e both super and subclass has the same method , subclass method is invoked . 4) Since the subclass variables are not initialized yet but has default values, it prints 3.Value of b is: 0. 5)Now the subclass initialization starts and b is assigned the value 126. 6)Then the subclass constructor is called which prints 2.Value of b is: 126. Hope I got it straight.
Here's the process for creating a new instance of a Class: First, memory space is allocated for all of the instance variables and those field are initialized to their default values. In our case, that means memory space is allocated for the variable b and it is set to 0. Next, the initialization procedure continues with these 5 steps: 1. Locate the approriate constructor for the object being created. 2. If that constructor begins with an invocation of another constructor within the same class, execution transfers to that constructor. Otherwise, continue with step 3. 3. If the constructor begins with an explicit invocation of the contructor of the parent class, locate that constructor and continue with step 4. If there is no explicit invocation of the constructor of the parent class, the default constructor of the parent class is invoked and we continue with step 4. Repeat this process for the superclass recursively using these 5 steps. 4. Execute instance initializers and variable initializers in textual order. 5. Execute the located constructor for this class. This is simply a paraphrased version of the steps listed in the JLS, §12.5 Creation of New Class Instances. So, in short, when you create a new instance of a class, the initializers of the superclass are executed, followed by the constructor of the superclass. Then, the initializers of the subclass (the one you instantiated) are executed, followed by the constructor of the subclass. So, what does that mean for our example. First, memory was allocated for b - it initially contains the value 0. Next, we execute the initializers for the superclass, Q21. That sets b to 127 (note, however, that this is not the same b as in the class SQ21 - that class has it's own b variable which oveshadows this one. Next, the constructor for the superclass is executed, which calls methodA. Using dynamic-binding, the methodA from the class SQ21 is called so we see the value of the b variable in the class SQ21, which is still 0. Now that initialization of the superclass is complete, we can initialize the subclass. The initializers for the subclass are executed, which sets the variable b (now we're initializing the one in the class SQ21) to 126. Finally, we invoke the constructor for the class SQ21, which, in turn, invokes the method methodA. Using dynamic-binding, we invoke the method in class SQ21, which prints the variable b from that class, which now contains the value 126. So, that's the process that's taking place. I hope everyone could follow that. It should also be noted that, before the class Q21 is initialized, the Object class is initialized (as Q21 implicitly extends Object). However, the initialization of the Object class doesn't do anything of significance. Initialization of superclasses is done recursively. Now, a couple quick questions for all of you. What would the output look like if we got rid of the variable b in the subclass, SQ21? What would the output look like if the following line was added as the first line of the constructor of Q21?
I hope this helps clear up any remaining doubts, Corey