简单的问题,奇怪的结果。我有两个课程A
和B
:
public class A
{
protected int num;
public A(int n)
{
num = n;
}
public boolean f(A a)
{
return num == a.num * 2;
}
}
public class B extends A
{
public B(int n)
{
super(n);
}
public boolean f(B b)
{
return num == b.num;
}
}
为什么y1.f(y2)
调用f()
而不是A
中的B
方法?
A y1 = new B(10);
B y2 = new B(10);
System.out.println(y1.f(y2));
是不是应该在f()
中拨打B
,因为B
比A
更具体?
答案 0 :(得分:32)
为什么y1.f(y2)调用A中的f()方法而不是B?
因为y1
的编译时类型是A
。
重载在编译时执行 ...您调用方法的对象的执行时类型仅与覆盖相关。
因此,编译器选择方法f(A)
,因为它是唯一可以在f
上调用的y1
方法(并且'}检查它是否适用于参数列表)。该方法未在B
中重写,因此在执行时,A
中的implmenetation被调用。
作为一个更为明显的例子,请考虑以下代码:
Object x = "foo";
int length = x.length();
这甚至无法编译,因为Object
不包含length()
方法。 String
确实如此,但编译器没有考虑到这一点,因为x
的编译时类型是Object
,而不是String
- 尽管我们可以告诉它在执行时,x
的值将是对String
对象的引用。