[英]Upcasting Objects - difference of static and non-static type
我有以下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作为输出?!?!?
发生这种情况是因为此代码段:
A.anotherMethod(b)
给您一个类型为A
的对象。 然后,您致电:
.someMethod(b)
在那种情况下。 现在,看到A
类不再具有someMethod(B b)
方法,它将改为调用someMethod(A a)
-之所以可以这样做,因为B
是A
的子类。
因为您在其上调用该方法的实例实际上是B
类型,并且B
类重写了someMethod(A a)
,该方法最终被调用,因此您的输出为7。
这是因为首先将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。
如果以更简单的方式编写相同场景的代码,那么一切将变得清晰:
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; }
}
因此,我们得到了“ casted”对象,它是B的实例,但被强制转换为A。当我们在其上调用someMethod(b)时,JVM会选择A.someMethod(B b)并执行其重写版本。 如果未显示A.someMethod(B b),则JVM选择A.someMethod(A a)并执行其覆盖版本。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.