繁体   English   中英

核心Java动态绑定

[英]Core Java Dynamic Binding

请告诉我们输出的原因。

按照我的说法,使用b.getx(),我们将获得B和b.getx().x的对象的引用ID b.getx().x应该获得10的值,但是当我运行此程序时,输出为5。

class Base {
  int x = 5;
  public Base getx() {
    return new Base();
  }
}

class Child extends Base {
  int x = 10;
  public Child getx() {
    return new Child();
  }

  public static void main(String ...s) {
    Base b = new Child();
    System.out.println(b.getx().x);
  }
}

字段访问(与方法调用不同)不受运行时动态调度的影响,它们仅基于编译时类型进行解析。

变量b是编译时类型Base ,因此b.getx()也是编译时类型Base ,因此b.getx().x将被编译为Base的x字段的访问,而不是Child的访问。 通过查看main方法的javap输出来确认这一点:

public static void main(java.lang.String[]);
  Code:
   0:   new #3; //class Child
   3:   dup
   4:   invokespecial   #4; //Method "<init>":()V
   7:   astore_1
   8:   getstatic   #5; //Field java/lang/System.out:Ljava/io/PrintStream;
   11:  aload_1
   12:  invokevirtual   #6; //Method Base.getx:()LBase;
   15:  getfield    #7; //Field Base.x:I
   18:  invokevirtual   #8; //Method java/io/PrintStream.println:(I)V
   21:  return

你可以看到b.getx().x被编译成Base.xgetfield指令。

动态绑定基本上意味着实际调用的方法实现是在运行时确定的,而不是在编译时确定的。 这就是为什么它被称为动态绑定 - 因为将在运行时选择将运行的方法。 动态绑定也称为后期绑定。

Base b = new Child(); 是在运行时和动态绑定规则(运行时多态)解决所有与此相关的方法应该在运行时绑定所以...

public Base getx() {
    return new Base();
  }

这些行返回基类的新实例,您只需在该实例上调用变量。

动态绑定是在运行时查看声明的运行时时间过程。 它也称为后期绑定,其中对重写方法的调用在运行时而不是编译时解析。 在面向对象的系统方法中,覆盖(动态多态)在运行时完成。 当用另一个方法覆盖一个方法时,两个方法的签名必须相同。

例:

class Animal{

  public void eat(){
      System.out.println("Animals voice");
   }

public void go(){
      System.out.println("Animals can walk");
   }

}

class Dog extends Animal{

   public void go(){
      System.out.println("Dogs can walk and run");
   }
   public void eat(){
      System.out.println("Dogs can eat a wide range of foods");
   }
}

暂无
暂无

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

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