静态和动态绑定的概念

时间:2014-12-23 15:44:29

标签: 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 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是Person的子类。这两个类都重写了toString方法。还有一个类打印机,它有2个人和专家对象的方法。我理解前3行:它调用打印机类并执行匹配类型的方法。第3行将对象动态转换为person对象。但我不明白第6行:为什么对象的转换不会改变被调用的方法。它不是由动态类型调用而是静态类型吗?

2 个答案:

答案 0 :(得分:0)

如果在超级对象上声明了方法,则可以在没有编译错误的情况下调用它,这是早期绑定/静态多态。将执行哪种方法取决于对象的动态类型,这是后期绑定/动态多态。

例如:

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

答案 1 :(得分:0)

在java中,所有被覆盖的方法都是虚拟方法,如here所述。这与其他语言(如C ++)不同,您需要使用 virtual 关键字来获取此行为。

来自维基百科:

  

虚拟功能已经解决,而且已经很晚了。如果有问题的功能是虚拟的'在基类中,根据引用的对象的实际类型调用函数的派生类最多的实现,而不管指针或引用的声明类型如何。如果它不是“虚拟”,则该方法可以及早解决['并且根据声明的指针或引用类型选择被调用的函数。

由于在这种情况下只有虚方法,因此根据所引用对象的实际类型调用该函数 - 如果将其强制转换为某个基类对象,则无关紧要。