Win a copy of Spring Boot in Practice this week in the Spring forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Tim Cooke
  • Ron McLeod
  • Jeanne Boyarsky
  • Paul Clapham
Sheriffs:
  • Liutauras Vilda
  • Henry Wong
  • Devaka Cooray
Saloon Keepers:
  • Tim Moores
  • Stephan van Hulst
  • Tim Holloway
  • Al Hobbs
  • Carey Brown
Bartenders:
  • Piet Souris
  • Mikalai Zaikin
  • Himai Minh

Overiding / Initialization - Question from mock

 
Ranch Hand
Posts: 102
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Firstly I was not too clear about the subject of my thread! Sorry about that!
I tried this code from a mock test:

Result is:
Inside Sub's f()
0
Inside Sub's f()
2
Press any key to continue...
Question: Why do I get 0 the first time?
 
Ranch Hand
Posts: 3271
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The method f() is overridden in the subclass Sub. So, when the instance initializer executes in Super (int a = f(); ), the method f from class Sub is invoked, returning the value of Sub's instance variable b. However, we haven't yet initialized that variable because we must initializer superclasses before subclasses. Therefore, when b is returned, it is still 0, not 2. That's why you get the first 0.
I hope that helps,
Corey
 
Cowgirl and Author
Posts: 1589
5
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Howdy!
This is a fun one
The big issue to understand here is this:
Polymorphism works, even when an object is not yet fully-formed. The code you show steps into the middle of the object construction process for the instance of the subclass. Here's how it works... (I have left out a few steps which do not matter)
1) Class Test main() method begins
2) you say "new Sub()" which invokes the constructor for Sub().
And this part is crucial: when the constructor for Sub() is invoked, the value of 'b' in Sub is still 0. It has not yet been initialized to '2' (that happens only AFTER the Super constructor has finished).
3) Sub() immediately invokes the constructor of class Super()
4) When the Super() constructor is running, the a variable will be initialized. But what is it being initialized to? The return value of the f() method. HERE'S THE BIG QUESTION... *which* f() method?
5) The f() method of Sub runs! In other words, even though the Sub() constructor has not completed, and the Sub object is not yet fully formed, polymorphism still applies. So the f() method call in class Super still causes the Sub overriding version of f() to run! Because remember, it really *is* a Sub object, so the overriding method always runs.
6) Because the f() method in Sub is called *before* the Super() constructor has completed, look at what Sub's f() method returns... the value of 'b'. But the value of 'b' has not yet been initialized to its explicit value of '2', since *that* won't happen until after the Super() constructor runs to completion. So, for this brief moment in time, Sub's f() method returns the value of b, but b has not yet been set to 2, so it still has its default value of 0.
7) So the real issue is that 'a', in class Super, is assigned the return value of Sub's f() method, but BEFORE the Sub object is formed. So the value of 'a' will forever be the default value of 'b', from class Sub.
So when the line sup.a runs, you see the '0' which was the result of Sub's f() method running before the Sub object was *ready* to be run.
I'm hoping this makes a little sense. This is the classic "Shroedinger's object" state, when a subclass object is in the process of being formed, but part of the superclass uses methods that have been overridden by the subclass. This shows up in other issues to... for example, if you use an overridden method in the constructor of the superclass as follows:

Changing the code to what I have above will give you the same result (0 and 2), for the same reason -- the f() method that runs in the Super() constructor is the Sub overriding version of f(), NOT the one in Super(). So, we have the same problem. The Sub version of f() runs, but it returns the value of 'b' which (since the Super() constructor has not yet completed) is still set to the default value of 0.
Cheers,
Kathy
author, Head First Java (next month, from O'Reilly)
and whatever the heck my certification book is called, from Osborne/McGraw-Hill
 
Monisha Talwar
Ranch Hand
Posts: 102
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Corey,
Thanks.
I was expecting the overiding part of it...but I was not expecting to see b = 0...which as you explained is not yet initialized at that point, so we see 0...
Is there a good document I can read up that would explain this? I get confused with this stuff
 
Monisha Talwar
Ranch Hand
Posts: 102
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks Kathy,
Yet another awesome explination from you...thanks for taking the time to elaborate every step...it really helped...
And by the way your absolutely COOL certification book which is the best ever is called: Sun Certified Programmer & Developer for Java 2 Study Guide (Exam 310-035 & 310-027)
Thanks again,
Monisha.
 
Don't get me started about those stupid light bulbs.
reply
    Bookmark Topic Watch Topic
  • New Topic