Hiding of instance variables. Hard question?

Discussion in 'Java' started by maxw_cc, Jan 21, 2004.

  1. maxw_cc

    maxw_cc Guest

    Hi Everybody...

    I was taking mock exam JavaRanch Rules (new Beta version) and I
    noticed the following interesting question (question #159). I have
    taken the license to rewrite it here:

    What is the output of:??

    class Exam {
    protected String difficultyLevel = "easy";
    public void printDifficultyLevel() {
    System.out.println( difficultyLevel );
    }
    }

    class SCJPExam extends Exam {
    private String difficultyLevel = "killing";
    }

    class TestExam {
    public static void main(String[] args) {
    SCJPExam myExam = new SCJPExam();
    myExam.printDifficultyLevel();
    }
    }

    According to JLS Section 8.3:
    ....
    "If the class declares a field with a certain name, then the
    declaration of that field is said to hide any and all accessible
    declarations of fields with the same name in superclasses, and
    superinterfaces of the class."
    ....

    And then later on:
    ....
    "A class inherits from its direct superclass and direct
    superinterfaces all the non-private fields of the superclass and
    superinterfaces that are both accessible to code in the class and not
    hidden by a declaration in the class."
    ....

    Well according to this I would have expected the String "killing"
    to be displayed rather than "easy". But to my surprise "easy"
    is displayed...!?!? Why?


    Unfortunately I was not totally convinced by the explanation given in
    the mock exam: "Methods can be overridden. Attributes Cannot" Yes I
    know that. But attributes can indeed be hidden in subclasses!!!

    According to Kathy Sierra and Bert Bates in their SCJP Study Guide
    page
    70, paragraph 1:

    "...Remember, if a subclass inherits a member, it’s
    exactly as if the subclass actually declared the member itself. In
    other words, if a subclass inherits a member, the subclass has the
    member."

    Then according to this, the aforementioned code could be equivalent to
    this one:

    class Exam {
    protected String difficultyLevel = "easy";
    }

    class SCJPExam extends Exam {
    private String difficultyLevel = "killing";
    public void printDifficultyLevel() {
    System.out.println( difficultyLevel );
    }
    }

    class TestExam {
    public static void main(String[] args) {
    SCJPExam myExam = new SCJPExam();
    myExam.printDifficultyLevel();
    }
    }

    And now you get "killing" instead of "easy"...!?! Why different now?
    By the way this was the behavior I was expecting always.

    Could anybody please explain me or point to anything in JLS that could
    bring light to this issue?

    Thanks a lot in advance...
    maxw_cc, Jan 21, 2004
    #1
    1. Advertising

  2. "maxw_cc" <> wrote in message
    news:...
    > Hi Everybody...
    >
    > I was taking mock exam JavaRanch Rules (new Beta version) and I
    > noticed the following interesting question (question #159). I have
    > taken the license to rewrite it here:
    >
    > What is the output of:??
    >
    > class Exam {
    > protected String difficultyLevel = "easy";
    > public void printDifficultyLevel() {
    > System.out.println( difficultyLevel );
    > }
    > }
    >
    > class SCJPExam extends Exam {
    > private String difficultyLevel = "killing";
    > }
    >
    > class TestExam {
    > public static void main(String[] args) {
    > SCJPExam myExam = new SCJPExam();
    > myExam.printDifficultyLevel();
    > }
    > }
    >
    > According to JLS Section 8.3:
    > ...
    > "If the class declares a field with a certain name, then the
    > declaration of that field is said to hide any and all accessible
    > declarations of fields with the same name in superclasses, and
    > superinterfaces of the class."
    > ...
    >
    > And then later on:
    > ...
    > "A class inherits from its direct superclass and direct
    > superinterfaces all the non-private fields of the superclass and
    > superinterfaces that are both accessible to code in the class and not
    > hidden by a declaration in the class."
    > ...
    >
    > Well according to this I would have expected the String "killing"
    > to be displayed rather than "easy". But to my surprise "easy"
    > is displayed...!?!? Why?



    SCJPExam.difficulty level, as you say, *hides* Exam.difficultyLevel, it
    doesn't *override* it. That is, in the scope SCJPExam, difficultyLevel
    means SCJPExam.difficultyLevel. That doesn't change the fact that in the
    scope Exam, difficultyLevel means Exam.difficultyLevel. In the line:

    System.out.println( difficultyLevel );

    difficultyLevel is bound at compile-time (not run-time) to
    Exam.difficultyLevel.

    In other word, fields, unlike methods, are never virtual.
    Mike Schilling, Jan 21, 2004
    #2
    1. Advertising

  3. maxw_cc

    Marc Dzaebel Guest

    "maxw_cc" <> schrieb im Newsbeitrag
    news:...

    use

    System.out.println( getClass().getField("difficultyLevel").get(this) )

    to simulate virtual fields (which is of course quite slow and exceptions
    have to be catched).

    E.g.

    class VirtualFieldAccess {
    public static void main(String[] args) {
    try { System.out.println(new A().c());
    System.out.println(new B().c());
    } catch (Exception e) { e.printStackTrace();}
    }
    }
    class A {
    public String c="a";
    Object c() throws Exception { return getClass().getField("c").get(this);}}
    class B extends A {
    public String c="b";
    }

    will print "a" and "b" respectively.
    Marc Dzaebel, Jan 22, 2004
    #3
  4. maxw_cc

    maxw_cc Guest

    "Mike Schilling" <> wrote in message news:<k2DPb.14254$>...
    > In other word, fields, unlike methods, are never virtual.


    Thank you very much to Mike and Marc for your good and useful
    answers.

    Specially thanks to Mike for pointing out that fields are
    fully resolved at compile time, using the field declaration at scope
    in compile time.
    maxw_cc, Jan 22, 2004
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    10
    Views:
    35,881
    jporter892
    Jun 6, 2011
  2. Eric D.
    Replies:
    3
    Views:
    179
    Jeremy Henty
    Feb 1, 2006
  3. Tammo Tjarks
    Replies:
    2
    Views:
    284
    Tammo Tjarks
    Sep 13, 2007
  4. Ralph Shnelvar
    Replies:
    29
    Views:
    772
    David Masover
    Nov 30, 2009
  5. Ste
    Replies:
    41
    Views:
    808
    Thomas 'PointedEars' Lahn
    Aug 1, 2007
Loading...

Share This Page