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...