起初我是初学者
我看过很多教程,阅读了很多例子,甚至试图从JLS中理解这个主题,但我仍然有一些困惑或误解。
让我告诉你我无法理解的问题。
想象一下,我们有三个课程Parent
,Child1
,Child2
如下:
class Parent {
void doSmth(Object o) {
System.out.println("Parent.doSmth");
}
}
class Child1 extends Parent {
void doSmth(Object o) {
System.out.println("Child1.doSmth");
}
}
class Child2 extends Parent {
void doSmth(String s) {
System.out.println("Child2.doSmth");
}
}
class Test {
public static void main(String[] args) {
Parent p1 = new Child1();
Parent p2 = new Child2();
p1.doSmth("String");
p2.doSmth("String");
}
}
我理解的是,因为p1
和p2
的引用来自类型Parent
,所以编译器只能看到doSmth(Object)
。
对于p1.doSmth("String");
,编译器没有绑定它,因为有一个重写方法,所以它只是让它让JVM在运行时绑定它(动态绑定)。
而对于p2.doSmth("String");
,编译器绑定它,因为它没有找到它的重写方法(静态绑定)。
问题是,我所说的是真的吗?或者我有误解?如果它是假的,那么请告诉我在这种情况下编译器采取了哪些步骤?
如果这是真的,那么编译器如何期望p1.doSmth
它有一个重写方法(虽然它不知道它是真正的类型),而在p2.doSmth
它只是绑定它?我错过了什么吗?
对不起,这真让我头疼......
答案 0 :(得分:0)
试着总结一下讨论。根据需要进行编辑。
Java中的静态绑定发生在编译时,而动态绑定发生在运行时。
在编译时,p1和p2都是Parent的类型,Parent有doSmth(Object)方法,因此两行都绑定到同一个方法。
p1.doSmth("String");
p2.doSmth("String");
在运行时,动态绑定进入画面。
p1是Child1的实例,Child1重写了doSmth(Object),因此使用了Child1的实现。
p2是Child2的实例,而Child2不会覆盖doSmth(Object),因此会调用Parent中继承方法的实现。