简体   繁体   English

指向基类的动态多态性引用

[英]dynamic polymorphism reference pointing to base class

I need a clarification in Dynamic polymorphism of Java. 我需要澄清Java的动态多态性。

class Foo {
  int a=3;
  public void display() {
    System.out.println(" in foo "+a);
  }
}

class Bar extends Foo {
  int a=8;
  public void display() {
    System.out.println(" in boo "+a);
  }
}

public class Tester {
 public static void main(String[]args) {
  Foo f = new Bar();
  f.display();
  System.out.println(f.a);
 }
}

Here when i create a child class object with a base class reference , while invoking the method f.display() it gives me the output as in boo 8 . 这里当我创建一个带有基类引用的子类对象时,在调用方法f.display()它给出了in boo 8的输出。 This is because of dynamic polymorphism which checks the object type at run time for invoking the method. 这是因为动态多态性在运行时检查对象类型以调用方法。

Now while printing fa it prints 3 because the variables cannot be overridden in java this is called hiding.That is why it is displaying the base variable value not the child variable value. 现在在打印fa它打印3因为变量无法在java中被覆盖,这称为隐藏。这就是它显示基本变量值而不是子变量值的原因。

Now my question is f is a reference of base class which is pointing to the child class object. 现在我的问题是f是基类的引用,它指向子类对象。 Then how fa points to the base variable.? 然后fa如何指向基本变量。 what happens behind the scene ? 场景背后会发生什么? How the reference is pointing to the base class ? 引用如何指向基类?

(I know the rules , but i want to know how/why ? ) (我知道规则,但我想知道如何/为什么?)

I don't know if this is outside what you've learned, but here it is. 我不知道这是否超出了你的学习范围,但在这里。 When you compile your code, the compiler generates byte code which the JVM executes. 编译代码时,编译器会生成JVM执行的字节代码。

The reference to the field Foo.a in fa in the line Foo.afa的字段Foo.a的引用

System.out.println(f.a);

gets compiled to 被编译到

getfield      #6                  // Field Foo.a:I

where getfield is a bytecode instruction which 其中getfield一个字节码指令

get a field value of an object objectref, where the field is identified by field reference in the constant pool index (index1 << 8 + index2) 获取对象objectref的字段值,其中字段由常量池索引中的字段引用标识(index1 << 8 + index2)

and the constant pool 和恒定的池

Constant pool:
   // [...]
   #6 = Fieldref           #20.#24        //  Foo.a:I
   // [...]

So the byte code is referencing the field in class Foo , the declared type of the variable, rather than in the run time class type of the instance. 因此,字节代码引用类Foo的字段,即变量的声明类型,而不是实例的运行时类类型。


You can look at the generated byte code with the following command 您可以使用以下命令查看生成的字节代码

javap -c -v YourClass

This is because of what you have already stated in your question: 这是因为您在问题中已经说明了这一点:

variables cannot be overridden in Java 变量不能在Java中重写

Therefore, reference fa is resolved statically at compile time, and it brings the compiler to Foo.a , which is 3 . 因此,引用fa在编译时静态解析,它将编译器带到Foo.a ,即3

Because variables cannot be overridden and you give the reference from base class that why its 因为变量不能被覆盖,所以你从基类中给出了它的原因

print f.a = 3 

if you declare like this 如果你这样宣布

Bar f = new Bar();

and now you print the value of fa it gives you 8 现在你打印fa的值给它8

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM