我很难理解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行:为什么对象的转换不会改变被调用的方法。它不是由动态类型调用而是静态类型吗?
答案 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 关键字来获取此行为。
来自维基百科:
虚拟功能已经解决,而且已经很晚了。如果有问题的功能是虚拟的'在基类中,根据引用的对象的实际类型调用函数的派生类最多的实现,而不管指针或引用的声明类型如何。如果它不是“虚拟”,则该方法可以及早解决['并且根据声明的指针或引用类型选择被调用的函数。
由于在这种情况下只有虚方法,因此根据所引用对象的实际类型调用该函数 - 如果将其强制转换为某个基类对象,则无关紧要。