我现在正在阅读一本Java书,并且已经停留了很长一段时间,现在正在思考Dynamic Method Dispatch的工作原理。我知道它是一个强大而有价值的功能,但我不了解它的主要原则。例如,我有一个继承自A类的B类,并覆盖了A的一些方法。所以,当我编写程序时,我可以使用这些表达式
A a = new B();
a.someOverridenMethod();
我知道在这种情况下会调用方法的版本B,而不是A.但是我不理解的部分是,为什么编译器无法确定哪个版本(超类或某些子类) )方法调用?我的意思是,它明确声明变量a
将保存对类型B的对象的引用。那么为什么只有在运行时才能确定它,即使它在码?
答案 0 :(得分:4)
更明确的例子可能是:
A a = null;
if (getUserInput() == 'B')
{
a = new B();
}
else
{
a = new C();
}
a.overridenMethod();
编译器可以可能知道将要调用哪个方法 - 用户在运行时确定它!
答案 1 :(得分:1)
你完全误解了运行时的事情。
这意味着class A
可以保存将在运行时确定的任何子类的引用。他们可能会在a =new C();
之后发表A a = new B();
之类的其他陈述,因为它们可以是这样的许多陈述,因此它说该方法的版本将在运行时确定
即。 a
将保留B
的引用,并且可能在其他时刻它将保留C
的引用,其中B
和C
是子类别A
以下是一个例子:
class A {
void override()
{
System.out.println("Inside A");
}
}
class B extends A
{
void override()
{
System.out.println("Inside B");
}
}
class C extends A
{
void override()
{
System.out.println("Inside C");
}
}
class Main
{
public static void main(String args[])
{
A a =new A();
a.override();
a=new B();
a.override();
a=new C();
a.override();
}
}
<强>输出:强>
Inside A
Inside B
Inside C
希望这可以解除你的怀疑。