Java 与这个简单的多态性示例相混淆
请查看此代码:Java 与这个简单的多态性示例相混淆,java,polymorphism,Java,Polymorphism,请查看此代码: class Foo { public int a; public Foo() { a = 3; } public void addFive() { a += 5; } public int getA() { System.out.println("we are here in base class!"); return a; } } public class
class Foo {
public int a;
public Foo() {
a = 3;
}
public void addFive() {
a += 5;
}
public int getA() {
System.out.println("we are here in base class!");
return a;
}
}
public class Polymorphism extends Foo{
public int a;
public Poylmorphism() {
a = 5;
}
public void addFive() {
System.out.println("we are here !" + a);
a += 5;
}
public int getA() {
System.out.println("we are here in sub class!");
return a;
}
public static void main(String [] main) {
Foo f = new Polymorphism();
f.addFive();
System.out.println(f.getA());
System.out.println(f.a);
}
}
在这里,我们将类多态性对象的引用指定给类型为Foo
的变量,即经典的polmorphism。现在我们调用方法addFive
,该方法在类多态性中被重写。然后,我们从getter方法打印变量值,该方法也在类多态性中被重写。所以我们得到的答案是10。但是当公共变量a
被SOP'ed时,我们得到了答案3
这是怎么发生的?尽管引用变量类型是Foo,但它引用的是多态类的对象。那么,为什么访问f.a
不会导致类polymorphics
中的a值被打印出来呢?请帮助您正在隐藏多态性的a
——您应该得到一个编译器警告。因此,这是两个不同的a
字段。与方法相反,字段不能是虚拟的。好的做法是根本不使用公共字段,而只使用改变私有状态(封装)的方法
如果要使其成为虚拟的,则需要将其作为具有访问器方法的属性(例如,您拥有的:getA
)。这是因为您不能重写类变量。当访问一个类变量时,引用的类型,而不是对象的类型,决定了您将得到什么
如果删除子类中a的重新声明,那么我认为行为将更符合预期。有一件事可能会澄清这一点,那就是查找“alpha重命名”的定义这就是这里发生的道德问题。为什么在调用方法时检查对象类型,在获取字段时检查类类型?如果变量也被对象类型引用,结果会是什么?@Shades88,查找虚拟字段意味着执行“getter”代码。字段是对象数据中的偏移量,而方法独立于实际对象数据;它们的地址存储在虚拟方法表中,每个类只存在一次。方法只是在指向对象数据的指针中传递,它们不是数据的一部分。请注意,只要字段是私有的,这就变得无关紧要了,因为除了声明字段的类的方法之外,没有其他代码可以看到它。@Shades88,我确实做了一些与编译器相关的工作,尽管不是在Java世界。快速回顾:“final”(非虚拟)方法在内存中有一个固定地址,它们被调用,第一个参数是“this”(例如实例)。请注意,调用本身不需要了解或访问实例。字段访问是不同的:对于给定类型,字段数据存储在实例数据的哪个偏移量处是已知的。所以这个+field_偏移指向字段数据。现在在普通的OO运行时中,第一个字段是指向类数据的隐藏字段。(续)此类数据不仅用于确定类型,还包含虚拟方法表(VT)。因此,就像一个字段的偏移量在实例数据中是已知的一样,每个虚拟方法在VT中的指针都有一个已知的偏移量,当调用虚拟调用时,编译器只需加载该方法的VT项并调用该指针。请注意,这对实例的内存布局没有任何影响,对于相同的方法,VT中的索引也总是相同的。所以可以说字段是虚拟的,除非你像方法一样执行alpha重命名。哦……那么你能解释一下为什么会这样吗?我的意思是,如果变量也被覆盖,会有什么影响?因为调用mmethods时检查对象类型和获取字段时检查类类型听起来很奇怪;)引用类型决定哪些方法和变量可用于调用。多态性的作用是覆盖这些可用方法的行为。但是,由于不能重写类变量,因此始终会在引用类型的类中获取变量的值。