Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/365.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 静态和动态绑定的概念_Java_Dynamic_Binding - Fatal编程技术网

Java 静态和动态绑定的概念

Java 静态和动态绑定的概念,java,dynamic,binding,Java,Dynamic,Binding,我在理解java中的动态绑定和继承方面有点困难。 下面是一段简短的代码: printer.print(person); // Printer is printing a person, which says: I am a Person printer.print(specialPerson); // Printer is printing a special pers

我在理解java中的动态绑定和继承方面有点困难。 下面是一段简短的代码:

 printer.print(person);                                  // Printer is printing a person, which says: I am a Person
    printer.print(specialPerson);                           // Printer is printing a special person, which says: I am a SpecialPerson
    printer.print((Person)specialPerson);                   // Printer is printing a person, which says: I am a SpecialPerson

    System.out.println(person);                             // I am a Person
    System.out.println(specialPerson);                      // I am a SpecialPerson
    System.out.println((Person)specialPerson);              // I am a SpecialPerson
    System.out.println(((Object)specialPerson).toString()); // I am a SpecialPerson

SpecialPerson在这里是一个儿童类的人。这两个类都重写了toString方法。还有一个类打印机,它有两个用于person和specialperson对象的方法。我理解前3行:它调用printer类并使用匹配类型执行方法。第三行将对象动态强制转换为person对象。但是我不理解第6行:为什么对象的转换不改变被调用的方法。它不是由动态类型调用的,而是由静态类型调用的吗?

如果在超级对象上声明了方法,则可以调用它而不会出现编译错误,这就是早期绑定/静态多态性。将执行哪个方法取决于对象的动态类型,这是后期绑定/动态多态性

例如:

public class Super {
   public void foo(){};
}

public class Sub extends Super {
   @Override 
   public void foo(){
      System.out.println("sub");
   }

  public void bar(){};
}


Super s1 = new Super();
Super s2 = new Sub();
Sub s3 = new Sub();


s1.foo(); //prints nothing
s2.foo(); // prints "sub"
s3.foo(); // prinss "sub"
s2.bar(); // won't compile even though s2 is really a Sub object

在java中,所有重写的方法都是虚拟方法,如下所述。这与其他语言不同,如C++,在这里你需要使用虚拟关键字来获得这种行为。 来自维基百科:

虚拟函数“延迟”解析。如果所讨论的函数在基类中是“虚拟”的,则根据所引用对象的实际类型调用最派生类的函数实现,而不管所声明的指针或引用类型如何。如果它不是“虚拟的”,则该方法将被解析为“早期的”,并根据所声明的指针或引用类型选择调用的函数


因为在这种情况下只有虚拟方法,所以函数是根据所引用对象的实际类型调用的——如果将其强制转换为某个基类对象,这并不重要。

因为specialperson仍然是specialperson,所以当我说:第6行中的强制转换操作符仅“更改”静态对象时,方法保持不变(type)但由于重写使用动态绑定,所以被调用的方法保持不变?