I'm training for a Java exam, and I've come across something I don't understand in last year subject. Here is the code
class Mother {
int var = 2;
int getVar() {
return var;
}
}
class Daughter extends Mother {
int var = 1;
int getVar() {
return var;
}
public static void main(String[] args) {
Mother m = new Mother();
System.out.println(m.var);
System.out.println(m.getVar());
m = new Daughter();
System.out.println(m.var);
System.out.println(m.getVar());
}
}
The question is "what is the output of this program?". I would have go with 2 2 1 1, but when compiling and running this piece of code, I get 2 2 2 1.
Anyone can explain me why ?
Thanks for reading !
The method call m.getVar()
is a virtual method call. The second time you call it, it's dynamically dispatched to the derived Daughter.getVar()
, which does what you expect (accesses Daugther.var
and returns that).
There is no such virtual dispatch mechanism for member fields. So m.var
always refers to Mother.var
, i.e. the base class's version of that variable.
The Daughter
class can be seen as having two different var
member: the one from Mother
and its own. Its own member "hides" the one in Mother
, but can be accessed from within the Daughter
class by using super.var
.
The official spec for this is in section 8.3 Field Declarations of the JLS. Quote:
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. The field declaration also shadows (§6.3.1) declarations of any accessible fields in enclosing classes or interfaces, and any local variables, formal method parameters, and exception handler parameters with the same name in any enclosing blocks.
Note that it can get pretty interesting (emphasis added):
If a field declaration hides the declaration of another field, the two fields need not have the same type.
And:
There might be several paths by which the same field declaration might be inherited from an interface. In such a situation, the field is considered to be inherited only once, and it may be referred to by its simple name without ambiguity.
So that paragraph is well worth reading :-)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With