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);
}
}
该类的执行结果为
男
null
结果使我感到困惑。当超类调用重写方法时,结果符合我的期望,但是当它调用重写变量时,结果使我感到困惑。那么为什么调用重写方法的超类引用看起来是多态的,但是如果它采用了重写成员变量,则不是吗?这是完整的代码。
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不允许您真正覆盖字段。
您BClass
实际上有两个字段sex
,一个来自AClass
,一个来自BClass
。Java语法并不能真正帮助您在编写类似的代码时找出哪一个意味着x.sex
。就像您在sex_a
in AClass
和sex_b
in中定义了两个不同的字段一样,BClass
只是复杂的是,对这两个字段的引用都像那样编写x.sex
,而没有明确提示这两个含义是在这里。
在您的情况下:
sex_b
初始化,并且为sex_a
空(空)。aClass.getSex()
始终根据实例的运行时类调用最特定的方法BClass
。因此它从中选择方法BClass
,返回sex_b
,从而打印性别。aClass.sex
sex
根据变量的可编译时可推断类型(在您的情况下为)访问两个字段之一AClass
。因此它将输出该sex_a
值,为null。经验丰富的Java开发人员通常会尽力避免这种情况,因为这可能会非常令人困惑。
如果两个字段在概念上具有相同的含义,请按照与该name
字段相同的方式进行操作,在父类中只有一个字段,并让子类通过getter和setter(或声明protected
该字段的可见性)对其进行访问。
如果这两个字段在概念上具有不同的含义(一个对象可以具有两种不同的性别吗?),请使用不同的名称。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句