Java 为什么调用重写方法的超类引用看起来是多态的,但如果它接受重写的成员变量?;
这个类的执行结果是Java 为什么调用重写方法的超类引用看起来是多态的,但如果它接受重写的成员变量?;,java,bytecode,Java,Bytecode,这个类的执行结果是 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()); Sys
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);
}
}
结果令我困惑。当超类调用重写的方法时,结果满足我的期望,但当它调用重写的变量时,结果让我感到困惑。那么,为什么调用重写的方法的超类引用看起来是多态的,而如果它使用重写的成员变量则不是多态的呢?下面是完整的代码
虽然可以重写方法,但不能重写子类中的字段;实际上,您只是用相同的名称声明了一个字段。要允许字段在子类中也可见,可以将其可见性更改为
受保护
或包专用(默认修饰符),如果两个类都在同一个包中
虽然可以重写方法,但不能重写子类中的字段;实际上,您只是用相同的名称声明了一个字段。要允许字段在子类中也可见,可以将其可见性更改为
受保护
或包专用(默认修饰符),如果两个类都在同一个包中
根据Java规范,实例变量在扩展时不会被子类从超类重写。根据Java规范,实例变量在扩展时不会被子类从超类重写。Java不允许您真正重写字段 您的
BClass
实际上有两个名为sex
的字段,一个来自AClass
,另一个来自BClass
。当您编写类似x.sex
的东西时,Java语法并不能真正帮助您找出这是什么意思。这就好像你定义了两个不同的字段,AClass
中的sex\u a
和BClass
中的sex\u b
,只是复杂的是,对这两个字段的引用都写得像x.sex
,没有明确的提示这两个字段是什么意思
就你而言:
- 您的b类实例将初始化其
,并且sex\u b
为空(null)sex\u a
aClass.getSex()。因此,它从
中选择方法,返回BClass
,从而打印性别sex\u b
访问两个aClass.sex
字段中的一个,具体取决于变量的编译时可推断类型(在您的情况下是sex
)。因此,它打印aClass
值,为空sex\u a
名称
字段一样,在父类中只有一个字段,并让子类通过getter和setter(或通过声明该字段的受保护
可见性)访问该字段
如果这两个字段在概念上有不同的含义(一个对象可以有两种不同的性别吗?),请使用不同的名称。Java不允许您真正重写字段 您的
BClass
实际上有两个名为sex
的字段,一个来自AClass
,另一个来自BClass
。当您编写类似x.sex
的东西时,Java语法并不能真正帮助您找出这是什么意思。这就好像你定义了两个不同的字段,AClass
中的sex\u a
和BClass
中的sex\u b
,只是复杂的是,对这两个字段的引用都写得像x.sex
,没有明确的提示这两个字段是什么意思
就你而言:
- 您的b类实例将初始化其
,并且sex\u b
为空(null)sex\u a
aClass.getSex()。因此,它从
中选择方法,返回BClass
,从而打印性别sex\u b
访问两个aClass.sex
字段中的一个,具体取决于变量的编译时可推断类型(在您的情况下是sex
)。因此,它打印aClass
值,为空sex\u a
名称
字段一样,在父类中只有一个字段,并让子类通过getter和setter(或通过声明该字段的受保护
可见性)访问该字段
如果两个字段在概念上有不同的含义(一个对象可以有两种不同的性别吗?),请使用不同的名称
男
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;
}
}
public class BClass extends AClass{
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;
}
}
public class AClass {
protected String name, 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;
}
}