public class A {
int method(A a) { return 1; }
static int method(B b) { return 2 + b.method((A)b); }
}
public class B extends A {
final int method(A a) { return 4 + super.method(a); }
int method(C c) { return 8 + this.method((B)c); }
}
public class C extends B {
int method(C c) { return 16 + method((A)c); }
}
public class Test {
public static void main(String[] args) {
A a = new A();
B b = new B();
C c = new C();
b.method(b); //returns 7 (4 + 2 + 1)
b.method(c); //returns 15 (8 + 4 + 2 + 1)
}
}
每个类都在自己的文件中。
为什么第一个呼叫返回7?对我来说,它应该返回其他的东西,因为调用了b.method(a),然后调用了a.(b),然后调用了b中的某个东西,而不是a.(a),为什么第二个调用返回了15?
2条答案
按热度按时间rm5edbpk1#
对于b,有效函数如下。
类b中的重写方法(a)
也是由于重载静态int方法(b)的原因
注意这里静态方法也可以在示例上调用。
现在什么时候
method
将被调用,因为方法已为多个参数重载它将查找参数适用的方法。此函数的函数调用堆栈
b.method(b); //returns 7 (4 + 2 + 1)
是来自类b方法(b)的调用返回2+b.method((a)b)
在类b中调用方法(a)返回4+super.method(a)//因为super,它调用的不是重写的方法(a)它调用的是原始方法
在类a中调用静态int方法(a)返回1
1 + 4 + 2 -> 7
为了b.method(c)
调用类b int method(c c)返回8+this.method((b)c);调用类b方法static int method(b b)返回2+b.method((a)b);
调用类b final int method(a)返回4+super.method(a);//调用not overwriten方法(a),因为super关键字
调用类a int方法(a)返回1
1 + 4 + 2 + 8 -> 15
vaj7vani2#
可以调用两个有效的方法
b.method(b);
:编译器选择更具体的一个-
method(B)
. 不管它是静态的。静态方法也可以在示例上调用。另请参阅:通过对象调用静态方法是“坏形式”吗?为什么?现在我们需要解决
b.method((A)b);
.b
的编译时类型为A
所以编译器只在A
. 参数表达式的编译类型也是A
. 唯一适用的方法是:在运行时,
b
发现是的示例B
,因此B
取而代之的是:现在我们决定
super.method(a);
. 这里涉及的类型与中的类型完全相同b.method((A)b);
,但我们正在使用super
,所以在B
,即A
,改为调用:为了
b.method(c);
,参数的编译时类型为C
,因此我们有三种适用的方法:同样,最具体的,
method(C)
被选中。然后我们决定
this.method((B)c);
. 这个问题的解决方法与b.method(b);
. 编译时类型是相同的。参数的运行时类型是C
对象并不重要,因为C
覆盖是method(C)
方法,解析时从未调用过b.method(b);
.