package main.java;
public class Demo {
public static void main(String[] args) {
BClass bClass=new BClass("han","男");
AClass aClass=bClass;
System.out.println(aClass.getSex());
System.out.println(aClass.sex);
}
}
The execution result of this class is
男
null
The results are confusing to me. When the superclass calls the overridden method, the results meet my expectations, but when it calls the overridden variable, the results confuse me.so why does a superclass reference calling an overridden method appear polymorphic, but not if it takes an overridden member variable?Here's the entire code.
package main.java;
public class Demo {
public static void main(String[] args) {
BClass bClass=new BClass("han","男");
AClass aClass=bClass;
System.out.println(aClass.getSex());
System.out.println(aClass.sex);
}
}
package main.java;
public class AClass {
private String name;
public String sex;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
}
package main.java;
public class BClass extends AClass{
private String sex;
public BClass(String name,String sex) {
this.sex = sex;
super.setName(name);
}
@Override
public String getSex() {
return sex;
}
@Override
public void setSex(String sex) {
this.sex = sex;
}
}
Java doesn't allow you to really override a field.
Your BClass
actually has two fields named sex
, one from AClass
, and one from BClass
. And Java syntax doesn't really help you finding out which one is meant when you write something like x.sex
. It's as if you had defined two different fields, sex_a
in AClass
and sex_b
in BClass
, only with the complication that references to both are written like x.sex
, without a clear hint which of the two is meant here.
In your case:
sex_b
initialized, and the sex_a
empty (null).aClass.getSex()
always calls the most specific method, based on the instance's runtime class, being BClass
. So it chooses the method from BClass
, returning sex_b
, and thus prints the sex.aClass.sex
accesses one of the two sex
fields, depending on the variable's compile-time-deducible type, in your case being AClass
. So it prints the sex_a
value, being null.Seasoned Java developers typically do their best to avoid this situation, as it can be very confusing.
If the two fields conceptually have the same meaning, do it as you did with the name
field, having only one field in the parent class, and have the subclass access it via getters and setters (or by declaring protected
visibility for the field).
If the two fields have conceptually different meanings (can an object have two different sexes?), use different names.