• 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
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Accessing superclass fields

 
Author
Posts: 42
7
Android Netbeans IDE Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
A few days ago I failed my OCA 1Z0-808. By three percentage points. Rebooting, resetting and starting everything anew. So here it goes...

Could someone please help me out with this? The following code

prints Child while I expected it to be Parent. My reasoning was that since the var s is static and therefore can be accessed directly, through its fully qualified name, it should've brought me face to face with Parent.

Same sad story when I make s non-static and attempt to access it through a Child object, as in the code:


By the look of things, I'm missing something, and this 'something' is so huge I can't even see it. For example, why the keyword super in the above code works as if it were this? What are the dark forces at play here?
 
Greenhorn
Posts: 17
2
  • Likes 2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I'll try my best at explaining what is going on, and if someone comes along and finds what I posted as incorrect, then kindly correct it.

First Code Block:

At the top S is declared as static and public(that's why you can access it from the subclass). In the subclass you reassign the S variable to "child", so when you call it, it prints child, because from your subclass you modified the parent variable s before printing it.

Second Code Block:

You call this.S which directly calls S after you reassigned the variable, same thing with super.s. However new Parent().S creates a new instance of the parent class, in that instance S is not static, so the change doesn't happen, so it's Parent.



 
Igor Soudakevitch
Author
Posts: 42
7
Android Netbeans IDE Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Fabulous. Thank you, Svetlana
So, just to recap, is my understanding correct that the use of super doesn't really differ from this unless we're talking about shadowed vars?
 
Svetlana Rosemond
Greenhorn
Posts: 17
2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Igor Soudakevitch wrote:Fabulous. Thank you, Svetlana
So, just to recap, is my understanding correct that the use of super doesn't really differ from this unless we're talking about shadowed vars?



It depends on what you're doing, for example, if the class is final and therefore can't be sublcasses then this.variablename refers to a variable declared within the scope of the class. Super.variablename refers to a variable that is declared within the parent class.

It just so happens because the variable s is public this.s and super.s refer to the same variable. If you were to declare a variable s within the subclass, then this.s would refer to the subclass s.

Here is an example:







When it comes to the shadowed vars, I'll have to do some more reading on that.

 
Igor Soudakevitch
Author
Posts: 42
7
Android Netbeans IDE Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I think I got it. Thanks!
 
Sheriff
Posts: 11604
178
Hibernate jQuery Eclipse IDE Spring MySQL Database AngularJS Tomcat Server Chrome Java
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Igor Soudakevitch,

First of all, a warm welcome to CodeRanch!

Igor Soudakevitch wrote:A few days ago I failed my OCA 1Z0-808. By three percentage points. Rebooting, resetting and starting everything anew. So here it goes...


Sorry to hear you have failed the exam. Can I ask which resources you have used during your preparation? If you are looking for some additional advice, the search function of this forum will provide you with a bunch of topics with advice to prepare (and ace) the OCA exam. Here are a few:
  • Studying so hard just to fail(1z0-808)
  • Failing Java SE 8 Programmer I
  • Bad Experience with OCA 7 exams
  • Any tricks about how to manage the 120 min for so many question?
  • second failed OCAJP
  • Need some advice after failing the exam


  • Igor Soudakevitch wrote:By the look of things, I'm missing something, and this 'something' is so huge I can't even see it. For example, why the keyword super in the above code works as if it were this? What are the dark forces at play here?


    You are spot-on, you are missing "something" really huge and important! That's why I like to know which resources you have used to prepare for this exam. The huge (and important) "something" you are missing here is the difference between a class (static) variable and an instance variable. The explanation provided by Svetlana Rosemond is spot-on Have a cow, Svetlana! I'll provide some additional information about both variables. Here we go!
    A class (static) variable is associated with the class, rather than with any object (instance). Only one copy of this class (static) variable exists and every instance of the class shares a class variable. Any object (instance) can change the value of a class (static) variable, but you can also manipulate class (static) variables without creating an instance of the class.
    It's a different story for instance (non-static) variables. Each object (instance) has its own distinct copies of the instance (non-static) variables. So if you change the value of an instance (non-static) variable of one object, it will not affect the value of that instance (non-static) variable of all other objects of that class.

    So let's adjust your first code snippet a little bitThe output of this code snippet will be "Child Child Child Child", because there's only one variable s and its original value is overwritten on line1. Because there exists only one copy of this class (static) variable, it will print each time the value "Child".

    Let's make similar adjustments to your second code snippetIf you execute this code snippet, "Child Child Parent Parent" will be printed. In this example you are using instance variables and each instance has its own copy of instance variables. On line2 you are referring to the instance variables of the instance you have created in the main() method. The value of instance variable s is changed on line1 and therefore "Child" is printed twice. But on line3 two new instances are created, each with its own copy of the instance variables. And because the value of the instance variable s of these newly created instances is not changed, "Parent" is printed twice.

    Hope it helps!
    Kind regards,
    Roel
     
    Roel De Nijs
    Sheriff
    Posts: 11604
    178
    Hibernate jQuery Eclipse IDE Spring MySQL Database AngularJS Tomcat Server Chrome Java
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Igor Soudakevitch wrote:I think I got it. Thanks!


    Let's see if you really understand it It's time for one of my famous pop quiz questions

    What's the result of this code snippet?

    Svetlana Rosemond wrote:When it comes to the shadowed vars, I'll have to do some more reading on that.


    When you are done reading about shadowing variables, you can give this pop quiz question a try too. This code snippet uses shadowing variables extensively

    Hope it helps!
    Kind regards,
    Roel
     
    Igor Soudakevitch
    Author
    Posts: 42
    7
    Android Netbeans IDE Java
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Thank you, Roel! I really appreciate what you are doing; every time I see any of your posts I just know that it will be up to the point and fun to read. Honestly

    Now, to the pet lion puzzle.

    You were right: I didn't get it; at least, not quite. Failed twice to solve the problem. It took me at least ten minutes to see the light. Here's what I was thinking:



    Line 16 creates an anonymous Lion object, calls on it its own doNameStuff() method with "Jack" as the method's parameter.
    Line 8 changes the arg name to lower case and assigns the resulting String (i.e., "jack") to the current object's field named name (i.e., this.name); this var's value will be printed on line 12.
    Line 9 creates an anonymous Animal object and sets its name to "ANIMAL". The current object is unaffected by this change because these two objects are separate.
    Line 10 creates another object referenced to as a and whose runtime type is actually Lion. Since the object is completely new - fresh from the owen, so to speak, - its fields are pristine and, therefore, its name is simply "Lion"…

    I do this mistake quite often: treating fields as if they were virtual methods; as soon as I see a superclass type to the left of new and a subclass on the right, a switch gets thrown in my head reminding me that "the ref type says which methods and fields are available in principle, and the actual type dictates the concrete implementation at runtime." What I tend to forget is that this rule talks about *implementation*, about overriding - and vars aren't overridden, they are shadowed. So from now on I'm going to use another mnemonic: "When it comes to overridden methods, actual type rules; when it comes to shadowed vars, ref type is the king". Hopefully, I got it now...

    Alright, trying to do the trick right this time:

    The object a's name is "Animal" precisely because its reference type *is* Animal. Were it Lion (as if created by Lion a = new Lion(); ), its name would have been Lion.

    Fair enough. Taking next step.

    The var name (which is going to be used in another slot in the printf stat) gets assigned "ANIMAL" on line 11.

    As for the new Lion().name slot, it should be easy by now: its value is "Lion" because the object itself is a Lion (unlike the Animal-type object created on line 10).

    Finally, super.name is "Animal" because this variable is shadowed by declaring a new var with the same name on line 5, and by prefixing super we access this var directly in the superclass. Should we opt for a simple re-assignment instead of shadowing, super.name would have become "Lion" because the change in the value would've affected the superclass, too.

    Placing all together, the code should print 'ANIMAL jack Lion Animal'.

    Incidently, making name on line 2 non-static does not affect the outcome… but doing it on line 5 does! (sighs) Another brainer to crack… I love Java (sighs again)…

    I have to run now - sorry! - but will be back soon to answer your question: how and what did I do to prepare myself for the exam.

    Meanwhile, many thanks again for helping me - and many others - to get a solid footing in the Java world!
     
    With a little knowledge, a cast iron skillet is non-stick and lasts a lifetime.
    reply
      Bookmark Topic Watch Topic
    • New Topic