我的问题可能不太清楚。通过这个例子,我可以进一步解释。 当我阅读为此Static vs Dynamic Binding Logic发布的答案时,我得到了这个问题。
除了Class B p (double i)
version 1:
import java.lang.*;
public class X
{
public static void main(String [] args)
{
B c = new A();
c.p(10);
c.p("AAA");
((A)c).p(10);
}
}
class B {
public void p(String s)
{
System.out.println("B: my string is " + s);
}
public void p(int i)
{
System.out.println("B: twice my double is: " + i*2);
}
}
class A extends B{
public void p(int i)
{
System.out.println("A: my number is " + i);
}
}
Here the output is :
A:my number is 10
B: my string is AAA
A: my number is 10
version 2:
import java.lang.*;
public class X
{
public static void main(String [] args)
{
B c = new A();
c.p(10);
c.p("AAA");
((A)c).p(10);
}
}
class B {
public void p(String s)
{
System.out.println("B: my string is " + s);
}
public void p(double i)
{
System.out.println("B: twice my double is: " + i*2);
}
}
class A extends B{
public void p(int i)
{
System.out.println("A: my number is " + i);
}
}
Here the output is :
B:twice my double is 20.0
B: my string is AAA
A: my number is 10
我的问题如下:
为什么在第一个版本中调用来自A类的p(int)
,而在第二个版本中调用来自B类的p(double)
。
version 1:
methods of A
A -----> p(string), p(int)- this is overridden from Class B
method of B
B ------> p(string), p(int)
version 2:
methods of A
A -----> p(string), p(double), p(int) No more overriding
method of B
B ------> p(string), p(double)
当我声明B c;
时,我初始化了B
类型的引用变量
接下来,我通过c = new A();
因此,这个声明B c = new A();
创建了一个A类实例并分配给B类变量。现在每当在c上执行方法调用时,编译器首先检查B中是否存在方法(因为它是B类型),但实际调用的方法是对象(它是一个A实例)。
为什么在上面的例子中没有看到这种行为?或者如果我的推理是错误的,请善意地纠正我。
谢谢
答案 0 :(得分:1)
在第一个版本中,覆盖一个方法,在第二个方法中重载。
在第一个版本中,您p
和class A
都有class B
。当您致电c.p(...)
时,编译器使用c
的静态类型来创建呼叫。在运行时,代码使用类的虚拟表(如果你不熟悉,请阅读它),以便找到正确的多态方法。
在第二个版本中,编译器在编译时上为您执行从int到double的转换,然后在运行时它再次使用A
的虚拟表来查找方法带有签名p(double)
(因为它在编译时为了静态类型的合规性而转换为int)。虚拟表指向B
中的方法,因为A
不会覆盖它。
您可以在“Effective Java”一书中找到相关内容 - 第41项,第191页:
selection among overloaded methods is static, while selection among overridden methods is dynamic