繁体   English   中英

上载对象-静态和非静态类型的差异

[英]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) -之所以可以这样做,因为BA的子类。

因为您在其上调用该方法的实例实际上是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。

您不能在Java中覆盖static方法。

即使您重写,也不会考虑或将其作为替代方法。

以下链接供您参考。

我可以覆盖和重载Java中的静态方法吗?

如果以更简单的方式编写相同场景的代码,那么一切将变得清晰:

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM