我有以下java代码:
class A {
int someMethod () { return 1; }
int someMethod (A a) { return 2; }
int someMethod (B b) { return 3; }
int someMethod (C c) { return 4; }
static A anotherMethod ( Object obj) { return (A) obj; }
}
class B extends A {
int someMethod () { return 6; }
int someMethod (A a) { return 7; }
int someMethod (B b) { return 8; }
int someMethod (C c) { return 9; }
static A anotherMethod ( Object obj) { return (B) obj; }
}
class C extends A {
int someMethod () { return 11; }
int someMethod (A a) { return 12; }
int someMethod (B b) { return 13; }
int someMethod (C c) { return 14; }
static C anotherMethod ( Object obj) { return (C) obj; }
}
public static void main ( String [] args ){
A a = new A(); B b = new B(); C c = new C();
System .out. println (A. anotherMethod (b). someMethod (b));
}
正如预期的那样,输出为8。
好的,我现在删除了A类中的someMethod(B b):
class A {
int someMethod () { return 1; }
int someMethod (A a) { return 2; }
int someMethod (C c) { return 4; }
static A anotherMethod ( Object obj) { return (A) obj; }
}
我与朋友讨论了输出,但是没有人能够解释为什么我们现在得到7输出?!?!???
答案 0 :(得分:3)
这是因为这个片段:
A.anotherMethod(b)
为您提供键入A
的对象。然后你打电话:
.someMethod(b)
在那个实例上。现在,看到A
类不再具有someMethod(B b)
方法,它将调用someMethod(A a)
- 它可以做,因为B
是一个子类A
。
因为您调用方法的实例实际上是B
类型,而B
类会覆盖someMethod(A a)
那个最终被调用的实例,因此您的输出7。
答案 1 :(得分:0)
这是因为你首先将B对象转换为A,然后在名为b的变量中有一个类型A的引用,当你将b传递给方法时,你实际传递的是对A的引用。
A.anotherMethod (b) // Casts and returns a reference of type A.
.someMethod(b) // What you really have here is a reference of type A
所以这将调用someMethod(A a),因此将输出7。
答案 2 :(得分:0)
您无法覆盖java中的static
方法。
即使你覆盖它也不会考虑或作为覆盖方法。
以下链接供您参考。
答案 3 :(得分:0)
如果以更简单的方式编码相同的场景,那么一切都变得清晰:
public class Playground {
public static void main(String[] args) throws Exception {
B b = new B();
A casted = (A) b;
System.out.println(casted.someMethod(b));
}
}
class A {
int someMethod(A a) { return 2; }
int someMethod(B b) { return 3; }
}
class B extends A {
int someMethod(A a) { return 7; }
int someMethod(B b) { return 8; }
}
因此,我们得到了#c;'对象是B的实例,但是被转换为A.当我们在其上调用someMethod(b)时,JVM选择A.someMethod(B b)并执行其覆盖版本。如果没有呈现A.someMethod(B b),JVM会选择A.someMethod(A a)并执行其覆盖版本。